#include "xf86.h"
#include "xf86_OSproc.h"
#include "xf86_ansic.h"
#include "compiler.h"
#include "xf86fbman.h"
#include "i830.h"
static void I830LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src);
static void I830ShowCursor(ScrnInfoPtr pScrn);
static void I830HideCursor(ScrnInfoPtr pScrn);
static void I830SetCursorColors(ScrnInfoPtr pScrn, int bg, int fb);
static void I830SetCursorPosition(ScrnInfoPtr pScrn, int x, int y);
static Bool I830UseHWCursor(ScreenPtr pScrn, CursorPtr pCurs);
void
I830InitHWCursor(ScrnInfoPtr pScrn)
{
I830Ptr pI830 = I830PTR(pScrn);
CARD32 temp;
DPRINTF(PFX, "I830InitHWCursor\n");
if (IS_MOBILE(pI830)) {
temp = INREG(CURSOR_A_CONTROL);
temp &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE | MCURSOR_MEM_TYPE_LOCAL |
MCURSOR_PIPE_SELECT);
temp |= CURSOR_MODE_DISABLE;
if (pI830->pipeEnabled[0])
temp |= MCURSOR_PIPE_A;
else if (pI830->pipeEnabled[1])
temp |= MCURSOR_PIPE_B;
OUTREG(CURSOR_A_CONTROL, temp);
OUTREG(CURSOR_A_BASE, pI830->CursorMem.Physical);
} else {
temp = INREG(CURSOR_CONTROL);
temp &= ~(CURSOR_FORMAT_MASK | CURSOR_GAMMA_ENABLE |
CURSOR_ENABLE | CURSOR_STRIDE_MASK);
temp |= (CURSOR_FORMAT_3C);
OUTREG(CURSOR_CONTROL, temp);
OUTREG(CURSOR_BASEADDR, pI830->CursorMem.Start);
temp = ((I810_CURSOR_X & CURSOR_SIZE_MASK) << CURSOR_SIZE_HSHIFT) |
((I810_CURSOR_Y & CURSOR_SIZE_MASK) << CURSOR_SIZE_VSHIFT);
OUTREG(CURSOR_SIZE, temp);
}
}
Bool
I830CursorInit(ScreenPtr pScreen)
{
ScrnInfoPtr pScrn;
I830Ptr pI830;
xf86CursorInfoPtr infoPtr;
DPRINTF(PFX, "I830CursorInit\n");
pScrn = xf86Screens[pScreen->myNum];
pI830 = I830PTR(pScrn);
pI830->CursorInfoRec = infoPtr = xf86CreateCursorInfoRec();
if (!infoPtr)
return FALSE;
infoPtr->MaxWidth = 64;
infoPtr->MaxHeight = 64;
infoPtr->Flags = (HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
HARDWARE_CURSOR_BIT_ORDER_MSBFIRST |
HARDWARE_CURSOR_INVERT_MASK |
HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK |
HARDWARE_CURSOR_AND_SOURCE_WITH_MASK |
HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64 | 0);
infoPtr->SetCursorColors = I830SetCursorColors;
infoPtr->SetCursorPosition = I830SetCursorPosition;
infoPtr->LoadCursorImage = I830LoadCursorImage;
infoPtr->HideCursor = I830HideCursor;
infoPtr->ShowCursor = I830ShowCursor;
infoPtr->UseHWCursor = I830UseHWCursor;
if (pI830->CursorNeedsPhysical && !pI830->CursorMem.Physical)
return FALSE;
I830HideCursor(pScrn);
return xf86InitCursor(pScreen, infoPtr);
}
static Bool
I830UseHWCursor(ScreenPtr pScreen, CursorPtr pCurs)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
I830Ptr pI830 = I830PTR(pScrn);
DPRINTF(PFX, "I830UseHWCursor\n");
if (pI830->CursorNeedsPhysical && !pI830->CursorMem.Physical)
return FALSE;
return TRUE;
}
static void
I830LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src)
{
I830Ptr pI830 = I830PTR(pScrn);
CARD8 *pcurs = (CARD8 *) (pI830->FbBase + pI830->CursorMem.Start);
int x, y;
DPRINTF(PFX, "I830LoadCursorImage\n");
for (y = 0; y < 64; y++) {
for (x = 0; x < 64 / 4; x++) {
*pcurs++ = *src++;
}
}
}
static void
I830SetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
{
I830Ptr pI830 = I830PTR(pScrn);
CARD32 temp = 0;
static Bool outsideViewport = FALSE;
Bool hide = FALSE, show = FALSE;
if (x >= pScrn->currentMode->HDisplay ||
y >= pScrn->currentMode->VDisplay ||
x <= -I810_CURSOR_X || y <= -I810_CURSOR_Y) {
hide = TRUE;
outsideViewport = TRUE;
} else if (outsideViewport) {
show = TRUE;
outsideViewport = FALSE;
}
if (x < 0) {
temp |= (CURSOR_POS_SIGN << CURSOR_X_SHIFT);
x = -x;
}
if (y < 0) {
temp |= (CURSOR_POS_SIGN << CURSOR_Y_SHIFT);
y = -y;
}
temp |= ((x & CURSOR_POS_MASK) << CURSOR_X_SHIFT);
temp |= ((y & CURSOR_POS_MASK) << CURSOR_Y_SHIFT);
OUTREG(CURSOR_A_POSITION, temp);
if (pI830->cursorOn) {
if (hide)
pI830->CursorInfoRec->HideCursor(pScrn);
else if (show)
pI830->CursorInfoRec->ShowCursor(pScrn);
pI830->cursorOn = TRUE;
}
}
static void
I830ShowCursor(ScrnInfoPtr pScrn)
{
I830Ptr pI830 = I830PTR(pScrn);
CARD32 temp;
DPRINTF(PFX, "I830ShowCursor\n");
DPRINTF(PFX,
"Value of CursorMem.Physical is %x, "
" Value of CursorMem.Start is %x ",
pI830->CursorMem.Physical, pI830->CursorMem.Start);
pI830->cursorOn = TRUE;
if (IS_MOBILE(pI830)) {
temp = INREG(CURSOR_A_CONTROL);
temp &= ~CURSOR_MODE;
temp |= CURSOR_MODE_64_4C_AX;
OUTREG(CURSOR_A_CONTROL, temp);
OUTREG(CURSOR_A_BASE, pI830->CursorMem.Physical);
} else {
temp = INREG(CURSOR_CONTROL);
temp |= CURSOR_ENABLE;
OUTREG(CURSOR_CONTROL, temp);
}
}
static void
I830HideCursor(ScrnInfoPtr pScrn)
{
CARD32 temp;
I830Ptr pI830 = I830PTR(pScrn);
DPRINTF(PFX, "I830HideCursor\n");
pI830->cursorOn = FALSE;
if (IS_MOBILE(pI830)) {
temp = INREG(CURSOR_A_CONTROL);
temp &= ~CURSOR_MODE;
temp |= CURSOR_MODE_DISABLE;
OUTREG(CURSOR_A_CONTROL, temp);
OUTREG(CURSOR_A_BASE, pI830->CursorMem.Physical);
} else {
temp = INREG(CURSOR_CONTROL);
temp &= ~CURSOR_ENABLE;
OUTREG(CURSOR_CONTROL, temp);
}
}
static void
I830SetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
{
I830Ptr pI830 = I830PTR(pScrn);
DPRINTF(PFX, "I830SetCursorColors\n");
OUTREG(CURSOR_A_PALETTE0, bg & 0x00ffffff);
OUTREG(CURSOR_A_PALETTE1, fg & 0x00ffffff);
OUTREG(CURSOR_A_PALETTE2, fg & 0x00ffffff);
OUTREG(CURSOR_A_PALETTE3, bg & 0x00ffffff);
}