apm_cursor.c revision 17a48c7c
117a48c7cSmrg/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/apm/apm_cursor.c,v 1.14 2000/06/30 18:27:02 dawes Exp $ */ 217a48c7cSmrg 317a48c7cSmrg#ifdef HAVE_CONFIG_H 417a48c7cSmrg#include "config.h" 517a48c7cSmrg#endif 617a48c7cSmrg 717a48c7cSmrg#include <X11/X.h> 817a48c7cSmrg#include <X11/Xproto.h> 917a48c7cSmrg#include "misc.h" 1017a48c7cSmrg#include "input.h" 1117a48c7cSmrg#include "cursorstr.h" 1217a48c7cSmrg#include "regionstr.h" 1317a48c7cSmrg#include "scrnintstr.h" 1417a48c7cSmrg#include "servermd.h" 1517a48c7cSmrg#include "windowstr.h" 1617a48c7cSmrg#include "mfb.h" 1717a48c7cSmrg#include "mipointer.h" 1817a48c7cSmrg 1917a48c7cSmrg#include "apm.h" 2017a48c7cSmrg 2117a48c7cSmrg#define CURSORWIDTH 64 2217a48c7cSmrg#define CURSORHEIGHT 64 2317a48c7cSmrg#define CURSORSIZE (CURSORWIDTH * CURSORHEIGHT / 8) 2417a48c7cSmrg#define CURSORALIGN ((CURSORSIZE + 1023) & ~1023l) 2517a48c7cSmrg 2617a48c7cSmrgstatic void ApmShowCursor(ScrnInfoPtr pScrn); 2717a48c7cSmrgstatic void ApmHideCursor(ScrnInfoPtr pScrn); 2817a48c7cSmrgstatic void ApmSetCursorPosition(ScrnInfoPtr pScrn, int x, int y); 2917a48c7cSmrgstatic void ApmSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg); 3017a48c7cSmrgstatic void ApmLoadCursorImage(ScrnInfoPtr pScrn, u8* data); 3117a48c7cSmrgstatic Bool ApmUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs); 3217a48c7cSmrg 3317a48c7cSmrgstatic u8 ConvertTable[256]; 3417a48c7cSmrg 3517a48c7cSmrg/* Inline functions */ 3617a48c7cSmrgstatic __inline__ void 3717a48c7cSmrgWaitForFifo(ApmPtr pApm, int slots) 3817a48c7cSmrg{ 3917a48c7cSmrg if (!pApm->UsePCIRetry) { 4017a48c7cSmrg volatile int i; 4117a48c7cSmrg#define MAXLOOP 1000000 4217a48c7cSmrg 4317a48c7cSmrg for(i = 0; i < MAXLOOP; i++) { 4417a48c7cSmrg if ((STATUS() & STATUS_FIFO) >= slots) 4517a48c7cSmrg break; 4617a48c7cSmrg } 4717a48c7cSmrg if (i == MAXLOOP) { 4817a48c7cSmrg unsigned int status = STATUS(); 4917a48c7cSmrg 5017a48c7cSmrg WRXB(0x1FF, 0); 5117a48c7cSmrg if (!xf86ServerIsExiting()) 5217a48c7cSmrg FatalError("Hung in WaitForFifo() (Status = 0x%08X)\n", status); 5317a48c7cSmrg } 5417a48c7cSmrg } 5517a48c7cSmrg} 5617a48c7cSmrg 5717a48c7cSmrgvoid ApmHWCursorReserveSpace(ApmPtr pApm) 5817a48c7cSmrg{ 5917a48c7cSmrg pApm->OffscreenReserved += 2 * CURSORALIGN; 6017a48c7cSmrg pApm->DisplayedCursorAddress = pApm->BaseCursorAddress = 6117a48c7cSmrg pApm->CursorAddress = 1024 * xf86Screens[pApm->pScreen->myNum]->videoRam - 6217a48c7cSmrg pApm->OffscreenReserved; 6317a48c7cSmrg} 6417a48c7cSmrg 6517a48c7cSmrg 6617a48c7cSmrgint ApmHWCursorInit(ScreenPtr pScreen) 6717a48c7cSmrg{ 6817a48c7cSmrg ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 6917a48c7cSmrg APMDECL(pScrn); 7017a48c7cSmrg xf86CursorInfoPtr infoPtr; 7117a48c7cSmrg u32 i; 7217a48c7cSmrg 7317a48c7cSmrg infoPtr = xf86CreateCursorInfoRec(); 7417a48c7cSmrg if (!infoPtr) 7517a48c7cSmrg return FALSE; 7617a48c7cSmrg 7717a48c7cSmrg pApm->CursorInfoRec = infoPtr; 7817a48c7cSmrg 7917a48c7cSmrg infoPtr->MaxWidth = CURSORWIDTH; 8017a48c7cSmrg infoPtr->MaxHeight = CURSORHEIGHT; 8117a48c7cSmrg 8217a48c7cSmrg infoPtr->Flags = HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_1; 8317a48c7cSmrg infoPtr->SetCursorColors = ApmSetCursorColors; 8417a48c7cSmrg infoPtr->SetCursorPosition = ApmSetCursorPosition; 8517a48c7cSmrg infoPtr->LoadCursorImage = ApmLoadCursorImage; 8617a48c7cSmrg infoPtr->HideCursor = ApmHideCursor; 8717a48c7cSmrg infoPtr->ShowCursor = ApmShowCursor; 8817a48c7cSmrg infoPtr->UseHWCursor = ApmUseHWCursor; 8917a48c7cSmrg 9017a48c7cSmrg /* Set up the convert table for the input cursor data */ 9117a48c7cSmrg for (i = 0; i < 256; i++) 9217a48c7cSmrg ConvertTable[i] = ((~i) & 0xAA) | (i & (i >> 1) & 0x55); 9317a48c7cSmrg 9417a48c7cSmrg return xf86InitCursor(pScreen, infoPtr); 9517a48c7cSmrg} 9617a48c7cSmrg 9717a48c7cSmrg 9817a48c7cSmrgstatic void 9917a48c7cSmrgApmShowCursor(ScrnInfoPtr pScrn) 10017a48c7cSmrg{ 10117a48c7cSmrg APMDECL(pScrn); 10217a48c7cSmrg 10317a48c7cSmrg WaitForFifo(pApm, 2); 10417a48c7cSmrg WRXW(0x144, pApm->CursorAddress >> 10); 10517a48c7cSmrg WRXB(0x140, 1); 10617a48c7cSmrg pApm->DisplayedCursorAddress = pApm->CursorAddress; 10717a48c7cSmrg} 10817a48c7cSmrg 10917a48c7cSmrg 11017a48c7cSmrgstatic void 11117a48c7cSmrgApmHideCursor(ScrnInfoPtr pScrn) 11217a48c7cSmrg{ 11317a48c7cSmrg APMDECL(pScrn); 11417a48c7cSmrg 11517a48c7cSmrg WaitForFifo(pApm, 1); 11617a48c7cSmrg WRXB(0x140, 0); 11717a48c7cSmrg} 11817a48c7cSmrg 11917a48c7cSmrgstatic Bool ApmUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs) 12017a48c7cSmrg{ 12117a48c7cSmrg return APMPTR(xf86Screens[pScreen->myNum])->CurrentLayout.bitsPerPixel >= 8; 12217a48c7cSmrg} 12317a48c7cSmrg 12417a48c7cSmrgstatic void 12517a48c7cSmrgApmSetCursorPosition(ScrnInfoPtr pScrn, int x, int y) 12617a48c7cSmrg{ 12717a48c7cSmrg APMDECL(pScrn); 12817a48c7cSmrg int xoff, yoff; 12917a48c7cSmrg 13017a48c7cSmrg if (x < -CURSORWIDTH || y < -CURSORHEIGHT) { 13117a48c7cSmrg WaitForFifo(pApm, 1); 13217a48c7cSmrg WRXB(0x140, 0); 13317a48c7cSmrg return; 13417a48c7cSmrg } 13517a48c7cSmrg 13617a48c7cSmrg if (x < 0) { 13717a48c7cSmrg xoff = -x; 13817a48c7cSmrg x = 0; 13917a48c7cSmrg } 14017a48c7cSmrg else 14117a48c7cSmrg xoff = 0; 14217a48c7cSmrg if (y < 0) { 14317a48c7cSmrg yoff = -y; 14417a48c7cSmrg y = 0; 14517a48c7cSmrg } 14617a48c7cSmrg else 14717a48c7cSmrg yoff = 0; 14817a48c7cSmrg 14917a48c7cSmrg WaitForFifo(pApm, 2); 15017a48c7cSmrg WRXW(0x14C, (yoff << 8) | (xoff & 0xFF)); 15117a48c7cSmrg WRXL(0x148, (y << 16) | (x & 0xFFFF)); 15217a48c7cSmrg} 15317a48c7cSmrg 15417a48c7cSmrg 15517a48c7cSmrgstatic void 15617a48c7cSmrgApmSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg) 15717a48c7cSmrg{ 15817a48c7cSmrg APMDECL(pScrn); 15917a48c7cSmrg u16 packedcolfg, packedcolbg; 16017a48c7cSmrg 16117a48c7cSmrg if (pApm->CurrentLayout.bitsPerPixel == 8) 16217a48c7cSmrg { 16317a48c7cSmrg WaitForFifo(pApm, 2); 16417a48c7cSmrg WRXB(0x141, fg); 16517a48c7cSmrg WRXB(0x142, bg); 16617a48c7cSmrg } 16717a48c7cSmrg else 16817a48c7cSmrg { 16917a48c7cSmrg packedcolfg = 17017a48c7cSmrg ((fg & 0xE00000) >> 16) | 17117a48c7cSmrg ((fg & 0x00E000) >> 11) | 17217a48c7cSmrg ((fg & 0x0000C0) >> 6); 17317a48c7cSmrg packedcolbg = 17417a48c7cSmrg ((bg & 0xE00000) >> 16) | 17517a48c7cSmrg ((bg & 0x00E000) >> 11) | 17617a48c7cSmrg ((bg & 0x0000C0) >> 6); 17717a48c7cSmrg WaitForFifo(pApm, 2); 17817a48c7cSmrg WRXB(0x141, packedcolfg); 17917a48c7cSmrg WRXB(0x142, packedcolbg); 18017a48c7cSmrg } 18117a48c7cSmrg} 18217a48c7cSmrg 18317a48c7cSmrg 18417a48c7cSmrgstatic void 18517a48c7cSmrgApmLoadCursorImage(ScrnInfoPtr pScrn, u8* data) 18617a48c7cSmrg{ 18717a48c7cSmrg APMDECL(pScrn); 18817a48c7cSmrg u32 i; 18917a48c7cSmrg u8 tmp[2 * CURSORSIZE]; 19017a48c7cSmrg 19117a48c7cSmrg /* Correct input data */ 19217a48c7cSmrg for (i = 0; i < sizeof tmp; i++) 19317a48c7cSmrg tmp[i] = ConvertTable[data[i]]; 19417a48c7cSmrg /* 19517a48c7cSmrg * To avoid flicker. 19617a48c7cSmrg * Note: 2*pApm->BaseCursorAddress + CURSORALIGN (=1024) < 2^31 all the time. 19717a48c7cSmrg */ 19817a48c7cSmrg pApm->CursorAddress = 2*pApm->BaseCursorAddress + CURSORALIGN - pApm->DisplayedCursorAddress; 19917a48c7cSmrg memcpy((u8*)pApm->FbBase + pApm->CursorAddress, tmp, sizeof tmp); 20017a48c7cSmrg} 201