summaryrefslogtreecommitdiff
path: root/src/apm_cursor.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/apm_cursor.c')
-rw-r--r--src/apm_cursor.c208
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);
+}