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