#include "newport.h"
#include "cursorstr.h"
#include "servermd.h"
#define MAX_CURS 32
static void NewportShowCursor(ScrnInfoPtr pScrn);
static void NewportHideCursor(ScrnInfoPtr pScrn);
static void NewportSetCursorPosition(ScrnInfoPtr pScrn, int x, int y);
static void NewportSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg);
static unsigned char* NewportRealizeCursor(xf86CursorInfoPtr infoPtr, CursorPtr pCurs);
Bool
NewportHWCursorInit(ScreenPtr pScreen)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
NewportPtr pNewport = NEWPORTPTR(pScrn);
NewportRegsPtr pNewportRegs = NEWPORTREGSPTR(pScrn);
xf86CursorInfoPtr infoPtr;
CARD16 tmp;
infoPtr = xf86CreateCursorInfoRec();
if(!infoPtr)
return FALSE;
pNewport->CursorInfoRec = infoPtr;
infoPtr->MaxWidth = MAX_CURS;
infoPtr->MaxHeight = MAX_CURS;
infoPtr->Flags = HARDWARE_CURSOR_TRUECOLOR_AT_8BPP;
infoPtr->SetCursorColors = NewportSetCursorColors;
infoPtr->SetCursorPosition = NewportSetCursorPosition;
infoPtr->LoadCursorImage = NewportLoadCursorImage;
infoPtr->HideCursor = NewportHideCursor;
infoPtr->ShowCursor = NewportShowCursor;
infoPtr->RealizeCursor = NewportRealizeCursor;
infoPtr->UseHWCursor = NULL;
pNewport->vc2ctrl |= VC2_CTRL_ECURS;
pNewport->vc2ctrl &= ~( VC2_CTRL_ECG64 | VC2_CTRL_ECCURS);
NewportBfwait(pNewportRegs);
pNewportRegs->set.dcbmode = (DCB_XMAP0 | R_DCB_XMAP9_PROTOCOL |
XM9_CRS_CURS_CMAP_MSB | NPORT_DMODE_W1 );
tmp = pNewportRegs->set.dcbdata0.bytes.b3;
#if 0
tmp++;
#endif
pNewportRegs->set.dcbmode = (DCB_XMAP0 | W_DCB_XMAP9_PROTOCOL |
XM9_CRS_CURS_CMAP_MSB | NPORT_DMODE_W1 );
pNewportRegs->set.dcbdata0.bytes.b3 = tmp;
pNewport->curs_cmap_base = (tmp << 5) & 0xffe0;
return xf86InitCursor(pScreen, infoPtr);
}
static void NewportShowCursor(ScrnInfoPtr pScrn)
{
NewportPtr pNewport = NEWPORTPTR(pScrn);
NewportRegsPtr pNewportRegs = NEWPORTREGSPTR(pScrn);
pNewport->vc2ctrl |= VC2_CTRL_ECDISP;
NewportVc2Set( pNewportRegs, VC2_IREG_CONTROL, pNewport->vc2ctrl);
}
static void NewportHideCursor(ScrnInfoPtr pScrn)
{
NewportPtr pNewport = NEWPORTPTR(pScrn);
NewportRegsPtr pNewportRegs = NEWPORTREGSPTR(pScrn);
pNewport->vc2ctrl &= ~VC2_CTRL_ECDISP;
NewportVc2Set( pNewportRegs, VC2_IREG_CONTROL, pNewport->vc2ctrl);
}
static void NewportSetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
{
CARD16 x_off;
NewportRegsPtr pNewportRegs = NEWPORTREGSPTR(pScrn);
NewportPtr pNewport = NEWPORTPTR(pScrn);
x_off = 31;
if ( pNewport->board_rev < 6 )
x_off = 21;
NewportVc2Set( pNewportRegs, VC2_IREG_CURSX, (CARD16) x + x_off);
NewportVc2Set( pNewportRegs, VC2_IREG_CURSY, (CARD16) y + 31);
}
static void NewportSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
{
NewportPtr pNewport = NEWPORTPTR(pScrn);
NewportRegsPtr pNewportRegs = NEWPORTREGSPTR(pScrn);
LOCO color;
color.blue = bg & 0xff;
color.green = (bg & 0xff00) >> 8;
color.red = (bg & 0xff0000) >> 16;
NewportCmapSetRGB( pNewportRegs, pNewport->curs_cmap_base+2, color);
color.blue = fg & 0xff;
color.green = (fg & 0xff00) >> 8;
color.red = (fg & 0xff0000) >> 16;
NewportCmapSetRGB( pNewportRegs, pNewport->curs_cmap_base+1, color);
}
static unsigned char* NewportRealizeCursor(xf86CursorInfoPtr infoPtr, CursorPtr pCurs)
{
int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2;
CARD32 *mem, *SrcS, *SrcM, *DstS;
unsigned int i;
if (!(mem = xcalloc(1, size)))
return NULL;
SrcS = (CARD32*)pCurs->bits->source;
SrcM = (CARD32*)pCurs->bits->mask;
DstS = mem;
for(i=0; i < pCurs->bits->height; i++) {
*DstS = *SrcS & *SrcM;
DstS++, SrcS++, SrcM++;
}
DstS = mem + MAX_CURS;
SrcS = (CARD32*)pCurs->bits->source;
SrcM = (CARD32*)pCurs->bits->mask;
for(i=0; i < pCurs->bits->height; i++) {
*DstS = (~*SrcS) & *SrcM;
DstS++, SrcS++, SrcM++;
}
return (unsigned char*) mem;
}
void NewportLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *bits)
{
int i;
CARD16 tmp;
NewportRegsPtr pNewportRegs = NEWPORTREGSPTR(pScrn);
tmp = NewportVc2Get( pNewportRegs, VC2_IREG_CENTRY);
NewportVc2Set( pNewportRegs, VC2_IREG_RADDR, tmp);
pNewportRegs->set.dcbmode = (NPORT_DMODE_AVC2 | VC2_REGADDR_RAM |
NPORT_DMODE_W2 | VC2_PROTOCOL);
for (i = 0; i < ((MAX_CURS * MAX_CURS) >> 3); i++) {
NewportBfwait(pNewportRegs);
pNewportRegs->set.dcbdata0.hwords.s1 = *(unsigned short*)bits;
bits += sizeof(unsigned short);
}
}