#include "via_driver.h"
static void VIALoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src);
static void VIASetCursorPosition(ScrnInfoPtr pScrn, int x, int y);
static void VIASetCursorColors(ScrnInfoPtr pScrn, int bg, int fg);
#define inCRReg(reg) (VGAHWPTR(pScrn))->readCrtc(VGAHWPTR(pScrn), reg)
#define outCRReg(reg, val) (VGAHWPTR(pScrn))->writeCrtc(VGAHWPTR(pScrn), reg, val)
#define inStatus1() (VGAHWPTR(pScrn))->readST01(VGAHWPTR(pScrn))
#define MAX_CURS 32
Bool
VIAHWCursorInit(ScreenPtr pScreen)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
VIAPtr pVia = VIAPTR(pScrn);
xf86CursorInfoPtr infoPtr;
DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIAHWCursorInit\n"));
infoPtr = xf86CreateCursorInfoRec();
if (!infoPtr)
return FALSE;
pVia->CursorInfoRec = infoPtr;
infoPtr->MaxWidth = MAX_CURS;
infoPtr->MaxHeight = MAX_CURS;
infoPtr->Flags = HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_32 |
HARDWARE_CURSOR_AND_SOURCE_WITH_MASK |
HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
HARDWARE_CURSOR_INVERT_MASK |
HARDWARE_CURSOR_BIT_ORDER_MSBFIRST|
0;
infoPtr->SetCursorColors = VIASetCursorColors;
infoPtr->SetCursorPosition = VIASetCursorPosition;
infoPtr->LoadCursorImage = VIALoadCursorImage;
infoPtr->HideCursor = VIAHideCursor;
infoPtr->ShowCursor = VIAShowCursor;
infoPtr->UseHWCursor = NULL;
if (!pVia->CursorStart) {
pVia->CursorStart = pVia->FBFreeEnd - VIA_CURSOR_SIZE;
pVia->FBFreeEnd -= VIA_CURSOR_SIZE;
VIASETREG(VIA_REG_CURSOR_MODE, pVia->CursorStart);
}
return xf86InitCursor(pScreen, infoPtr);
}
void
VIAShowCursor(ScrnInfoPtr pScrn)
{
VIAPtr pVia = VIAPTR(pScrn);
CARD32 dwCursorMode;
dwCursorMode = VIAGETREG(VIA_REG_CURSOR_MODE);
VIASETREG(VIA_REG_CURSOR_MODE, dwCursorMode | 0x3);
}
void
VIAHideCursor(ScrnInfoPtr pScrn)
{
VIAPtr pVia = VIAPTR(pScrn);
CARD32 dwCursorMode;
dwCursorMode = VIAGETREG(VIA_REG_CURSOR_MODE);
VIASETREG(VIA_REG_CURSOR_MODE, dwCursorMode & 0xFFFFFFFE);
}
static void
VIALoadCursorImage(ScrnInfoPtr pScrn, unsigned char* src)
{
VIAPtr pVia = VIAPTR(pScrn);
CARD32 dwCursorMode;
WaitIdle();
dwCursorMode = VIAGETREG(VIA_REG_CURSOR_MODE);
VIASETREG(VIA_REG_CURSOR_MODE, dwCursorMode & 0xFFFFFFFE);
memcpy(pVia->FBBase + pVia->CursorStart, src, MAX_CURS * MAX_CURS / 8 * 2);
VIASETREG(VIA_REG_CURSOR_MODE, dwCursorMode);
}
static void
VIASetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
{
VIAPtr pVia = VIAPTR(pScrn);
VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo;
unsigned char xoff, yoff;
CARD32 dwCursorMode;
if (x < 0) {
xoff = ((-x) & 0xFE);
x = 0;
} else {
xoff = 0;
}
if (y < 0) {
yoff = ((-y) & 0xFE);
y = 0;
} else {
yoff = 0;
if (pBIOSInfo->scaleY) {
y = (int)(((pBIOSInfo->panelY * y) + (pBIOSInfo->resY >> 1)) / pBIOSInfo->resY);
}
}
dwCursorMode = VIAGETREG(VIA_REG_CURSOR_MODE);
VIASETREG(VIA_REG_CURSOR_MODE, dwCursorMode & 0xFFFFFFFE);
VIASETREG(VIA_REG_CURSOR_ORG, ((xoff << 16) | (yoff & 0x003f)));
VIASETREG(VIA_REG_CURSOR_POS, ((x << 16) | (y & 0x07ff)));
VIASETREG(VIA_REG_CURSOR_MODE, dwCursorMode);
}
static void
VIASetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
{
VIAPtr pVia = VIAPTR(pScrn);
VIASETREG(VIA_REG_CURSOR_FG, fg);
VIASETREG(VIA_REG_CURSOR_BG, bg);
}