1/*
2   Voodoo Banshee driver version 1.0.2
3
4   Author: Daryll Strauss
5
6   Copyright: 1998,1999
7*/
8
9#ifdef HAVE_CONFIG_H
10#include "config.h"
11#endif
12
13#include "xf86.h"
14#include "xf86_OSproc.h"
15#include "xf86fbman.h"
16
17#include "tdfx.h"
18
19static void TDFXLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src);
20static void TDFXShowCursor(ScrnInfoPtr pScrn);
21static void TDFXHideCursor(ScrnInfoPtr pScrn);
22static void TDFXSetCursorPosition(ScrnInfoPtr pScrn, int x, int y);
23static void TDFXSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg);
24static Bool TDFXUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs);
25
26Bool
27TDFXCursorInit(ScreenPtr pScreen)
28{
29  ScrnInfoPtr pScrn;
30  TDFXPtr pTDFX;
31  xf86CursorInfoPtr infoPtr;
32
33  TDFXTRACECURS("TDFXCursorInit start\n");
34  pScrn = xf86ScreenToScrn(pScreen);
35  pTDFX = TDFXPTR(pScrn);
36  pTDFX->CursorInfoRec = infoPtr = xf86CreateCursorInfoRec();
37  if (!infoPtr) return FALSE;
38
39  infoPtr->MaxWidth = 64;
40  infoPtr->MaxHeight = 64;
41
42  infoPtr->Flags =
43#if X_BYTE_ORDER == X_LITTLE_ENDIAN
44HARDWARE_CURSOR_BIT_ORDER_MSBFIRST |
45#endif
46    HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK|
47    HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64 |
48    HARDWARE_CURSOR_TRUECOLOR_AT_8BPP;
49  infoPtr->SetCursorColors = TDFXSetCursorColors;
50  infoPtr->SetCursorPosition = TDFXSetCursorPosition;
51  infoPtr->LoadCursorImage = TDFXLoadCursorImage;
52  infoPtr->HideCursor = TDFXHideCursor;
53  infoPtr->ShowCursor = TDFXShowCursor;
54  infoPtr->UseHWCursor = TDFXUseHWCursor;
55
56  pTDFX->ModeReg.cursloc = pTDFX->cursorOffset;
57  pTDFX->writeLong(pTDFX, HWCURPATADDR, pTDFX->cursorOffset);
58
59  return xf86InitCursor(pScreen, infoPtr);
60}
61
62#if X_BYTE_ORDER == X_BIG_ENDIAN
63static unsigned int TDFXSwap(TDFXPtr pTDFX, unsigned int val) {
64  switch (pTDFX->cpp) {
65  default:
66    return val;
67  case 2:
68    return ((val & 0x00ff00ff) << 8) |
69	    ((val & 0xff00ff00) >> 8);
70  case 3:
71  case 4:
72    return BE_BSWAP32(val);
73  }
74}
75#endif
76
77static void
78TDFXLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src)
79{
80  TDFXPtr pTDFX;
81
82  TDFXTRACECURS("TDFXLoadCursorImage start\n");
83  pTDFX = TDFXPTR(pScrn);
84#if X_BYTE_ORDER == X_BIG_ENDIAN
85  {
86    int i;
87    unsigned int *ptr=(unsigned int *)(pTDFX->FbBase+pTDFX->cursorOffset);
88
89    for (i=0; i<256; i++) {
90      unsigned int val = ((unsigned int *)src)[i];
91      *ptr++ = TDFXSwap(pTDFX, val);
92    }
93  }
94#else
95  memcpy(pTDFX->FbBase+pTDFX->cursorOffset, src, 1024);
96#endif
97}
98
99static void
100TDFXShowCursor(ScrnInfoPtr pScrn)
101{
102  TDFXPtr pTDFX;
103
104  TDFXTRACECURS("TDFXShowCursor start\n");
105  pTDFX = TDFXPTR(pScrn);
106  pTDFX->ModeReg.vidcfg|=BIT(27);
107  pTDFX->writeLong(pTDFX, VIDPROCCFG, pTDFX->ModeReg.vidcfg);
108}
109
110void
111TDFXHideCursor(ScrnInfoPtr pScrn)
112{
113  TDFXPtr pTDFX;
114
115  TDFXTRACECURS("TDFXHideCursor start\n");
116  pTDFX = TDFXPTR(pScrn);
117  pTDFX->ModeReg.vidcfg&=~BIT(27);
118  pTDFX->writeLong(pTDFX, VIDPROCCFG, pTDFX->ModeReg.vidcfg);
119}
120
121static void
122TDFXSetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
123{
124  TDFXPtr pTDFX;
125
126  /* TDFXTRACECURS("TDFXSetCursorPosition start\n"); */
127  pTDFX = TDFXPTR(pScrn);
128  pTDFX->writeLong(pTDFX, HWCURLOC, ((y+64)<<16)|(x+64));
129}
130
131static void
132TDFXSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
133{
134  TDFXPtr pTDFX;
135
136  TDFXTRACECURS("TDFXSetCursorColors start\n");
137  pTDFX = TDFXPTR(pScrn);
138  pTDFX->writeLong(pTDFX, HWCURC0, bg);
139  pTDFX->writeLong(pTDFX, HWCURC1, fg);
140}
141
142static Bool
143TDFXUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs)
144{
145  ScrnInfoPtr pScrn;
146  TDFXPtr pTDFX;
147
148  TDFXTRACECURS("TDFXUseHWCursor start\n");
149  pScrn = xf86ScreenToScrn(pScreen);
150  pTDFX = TDFXPTR(pScrn);
151  if (pScrn->currentMode->Flags&V_DBLSCAN)
152    return FALSE;
153  if (!pTDFX->CursorInfoRec) return FALSE;
154  return TRUE;
155}
156