#ifdef HAVE_CONFIG_H
#include <kdrive-config.h>
#endif
#include "kdrive.h"
#include "kxv.h"
#include "i810.h"
#include "cursorstr.h"
#define SetupCursor(s) KdScreenPriv(pScreen); \
i810CardInfo(pScreenPriv); \
i810ScreenInfo(pScreenPriv); \
i810Cursor *pCurPriv = &i810s->cursor
static void
writeStandardMMIO(I810CardInfo *i810c, int addr, CARD8 val)
{
moutb(addr, val);
}
static void
_i810MoveCursor(ScreenPtr pScreen, int x, int y)
{
KdScreenPriv(pScreen);
i810CardInfo(pScreenPriv);
int flag;
if (I810_DEBUG & DEBUG_VERBOSE_CURSOR)
ErrorF( "I810SetCursorPosition %d %d\n", x, y);
x += i810c->CursorOffset;
if (x >= 0) flag = CURSOR_X_POS;
else {
flag = CURSOR_X_NEG;
x=-x;
}
OUTREG8( CURSOR_X_LO, x&0xFF);
OUTREG8( CURSOR_X_HI, (((x >> 8) & 0x07) | flag));
if (y >= 0) flag = CURSOR_Y_POS;
else {
flag = CURSOR_Y_NEG;
y=-y;
}
OUTREG8( CURSOR_Y_LO, y&0xFF);
OUTREG8( CURSOR_Y_HI, (((y >> 8) & 0x07) | flag));
OUTREG( CURSOR_BASEADDR, i810c->CursorPhysical);
OUTREG8( CURSOR_CONTROL, CURSOR_ORIGIN_DISPLAY | CURSOR_MODE_64_3C);
}
static void i810LoadCursor(ScreenPtr pScreen, int x, int y);
static void
i810MoveCursor (ScreenPtr pScreen, int x, int y)
{
KdScreenPriv(pScreen);
i810ScreenInfo(pScreenPriv);
i810Cursor *pCurPriv = &i810s->cursor;
if (!pCurPriv->has_cursor)
return;
if (!pScreenPriv->enabled)
return;
_i810MoveCursor (pScreen, x, y);
i810LoadCursor(pScreen, x, y);
}
static void
_i810SetCursorColors(ScreenPtr pScreen)
{
KdScreenPriv(pScreen);
i810CardInfo(pScreenPriv);
int tmp;
int bg = 0xffffff;
int fg = 0x000000;
tmp=INREG8(PIXPIPE_CONFIG_0);
tmp |= EXTENDED_PALETTE;
OUTREG8( PIXPIPE_CONFIG_0, tmp);
writeStandardMMIO(i810c, DACMASK, 0xFF);
writeStandardMMIO(i810c, DACWX, 0x04);
writeStandardMMIO(i810c, DACDATA, (bg & 0x00FF0000) >> 16);
writeStandardMMIO(i810c, DACDATA, (bg & 0x0000FF00) >> 8);
writeStandardMMIO(i810c, DACDATA, (bg & 0x000000FF));
writeStandardMMIO(i810c, DACDATA, (fg & 0x00FF0000) >> 16);
writeStandardMMIO(i810c, DACDATA, (fg & 0x0000FF00) >> 8);
writeStandardMMIO(i810c, DACDATA, (fg & 0x000000FF));
tmp=INREG8( PIXPIPE_CONFIG_0 );
tmp &= ~EXTENDED_PALETTE;
OUTREG8( PIXPIPE_CONFIG_0, tmp );
}
#define InvertBits32(v) { \
v = ((v & 0x55555555) << 1) | ((v >> 1) & 0x55555555); \
v = ((v & 0x33333333) << 2) | ((v >> 2) & 0x33333333); \
v = ((v & 0x0f0f0f0f) << 4) | ((v >> 4) & 0x0f0f0f0f); \
}
static void i810LoadCursor(ScreenPtr pScreen, int x, int y)
{
SetupCursor(pScreen);
int h;
unsigned int *msk, *mskLine, *src, *srcLine;
int i, j;
int src_stride, src_width;
CursorPtr pCursor = pCurPriv->pCursor;
CursorBitsPtr bits = pCursor->bits;
CARD8 tmp;
unsigned int *ram, *ramLine;
pCurPriv->pCursor = pCursor;
pCurPriv->xhot = pCursor->bits->xhot;
pCurPriv->yhot = pCursor->bits->yhot;
ramLine = (unsigned int *) (i810c->FbBase + i810c->CursorStart);
mskLine = (unsigned int *) (bits->mask);
srcLine = (unsigned int *) (bits->source);
h = bits->height;
if (h > I810_CURSOR_HEIGHT)
h = I810_CURSOR_HEIGHT;
src_stride = BitmapBytePad(bits->width);
src_stride = (src_stride +3) >> 2;
src_width = (bits->width + 31) >> 5;
for (i = 0; i < I810_CURSOR_HEIGHT; i++) {
msk = mskLine;
src = srcLine;
ram = ramLine;
mskLine += src_stride;
srcLine += src_stride;
ramLine += I810_CURSOR_WIDTH / 16;
for (j = 0; j < I810_CURSOR_WIDTH / 32; j++) {
unsigned long m, s;
if (i < h && j < src_width)
{
m = *msk++;
s = *src++ & m;
m = ~m;
if (j == src_width - 1 && (bits->width & 31))
{
m |= 0xffffffff << (bits->width & 31);
}
}
else
{
m = 0xffffffff;
s = 0x00000000;
}
InvertBits32(s);
InvertBits32(m);
ram[2+j]=s;
ram[0+j]=m;
}
}
_i810SetCursorColors (pScreen);
_i810MoveCursor (pScreen, x, y);
OUTREG( CURSOR_BASEADDR, i810c->CursorPhysical);
OUTREG8( CURSOR_CONTROL, CURSOR_ORIGIN_DISPLAY | CURSOR_MODE_64_3C);
tmp = INREG8( PIXPIPE_CONFIG_0 );
tmp |= HW_CURSOR_ENABLE;
OUTREG8( PIXPIPE_CONFIG_0, tmp);
}
static void
i810UnloadCursor(ScreenPtr pScreen)
{
KdScreenPriv(pScreen);
i810CardInfo(pScreenPriv);
unsigned char tmp;
tmp=INREG8( PIXPIPE_CONFIG_0 );
tmp &= ~HW_CURSOR_ENABLE;
OUTREG8( PIXPIPE_CONFIG_0, tmp);
}
static Bool
i810RealizeCursor (ScreenPtr pScreen, CursorPtr pCursor)
{
KdScreenPriv(pScreen);
i810ScreenInfo(pScreenPriv);
i810Cursor *pCurPriv = &i810s->cursor;
if (!pScreenPriv->enabled)
return TRUE;
if (pCurPriv->pCursor == pCursor)
{
if (pCursor)
{
int x, y;
miPointerPosition (&x, &y);
i810LoadCursor (pScreen, x, y);
}
}
return TRUE;
}
static Bool
i810UnrealizeCursor (ScreenPtr pScreen, CursorPtr pCursor)
{
return TRUE;
}
static void
i810SetCursor (ScreenPtr pScreen, CursorPtr pCursor, int x, int y)
{
KdScreenPriv(pScreen);
i810ScreenInfo(pScreenPriv);
i810Cursor *pCurPriv = &i810s->cursor;
pCurPriv->pCursor = pCursor;
if (!pScreenPriv->enabled)
return;
if (pCursor)
i810LoadCursor (pScreen, x, y);
else
i810UnloadCursor (pScreen);
}
miPointerSpriteFuncRec i810PointerSpriteFuncs = {
i810RealizeCursor,
i810UnrealizeCursor,
i810SetCursor,
i810MoveCursor,
};
static void
i810QueryBestSize (int class,
unsigned short *pwidth, unsigned short *pheight,
ScreenPtr pScreen)
{
KdScreenPriv(pScreen);
i810ScreenInfo(pScreenPriv);
i810Cursor *pCurPriv = &i810s->cursor;
switch (class)
{
case CursorShape:
if (*pwidth > pCurPriv->width)
*pwidth = pCurPriv->width;
if (*pheight > pCurPriv->height)
*pheight = pCurPriv->height;
if (*pwidth > pScreen->width)
*pwidth = pScreen->width;
if (*pheight > pScreen->height)
*pheight = pScreen->height;
break;
default:
fbQueryBestSize (class, pwidth, pheight, pScreen);
break;
}
}
Bool
i810CursorInit(ScreenPtr pScreen)
{
KdScreenPriv(pScreen);
i810ScreenInfo(pScreenPriv);
i810CardInfo(pScreenPriv);
i810Cursor *pCurPriv = &i810s->cursor;
if (!i810c->CursorStart) {
pCurPriv->has_cursor = FALSE;
return FALSE;
}
pCurPriv->width = I810_CURSOR_WIDTH;
pCurPriv->height= I810_CURSOR_HEIGHT;
pScreen->QueryBestSize = i810QueryBestSize;
miPointerInitialize (pScreen,
&i810PointerSpriteFuncs,
&kdPointerScreenFuncs,
FALSE);
pCurPriv->has_cursor = TRUE;
pCurPriv->pCursor = NULL;
return TRUE;
}
void
i810CursorEnable (ScreenPtr pScreen)
{
KdScreenPriv(pScreen);
i810ScreenInfo(pScreenPriv);
i810Cursor *pCurPriv = &i810s->cursor;
if (pCurPriv->has_cursor)
{
if (pCurPriv->pCursor)
{
int x, y;
miPointerPosition (&x, &y);
i810LoadCursor (pScreen, x, y);
}
else
i810UnloadCursor (pScreen);
}
}
void
i810CursorDisable (ScreenPtr pScreen)
{
KdScreenPriv(pScreen);
i810ScreenInfo(pScreenPriv);
i810Cursor *pCurPriv = &i810s->cursor;
if (!pScreenPriv->enabled)
return;
if (pCurPriv->has_cursor)
{
if (pCurPriv->pCursor)
{
i810UnloadCursor (pScreen);
}
}
}
void
i810CursorFini (ScreenPtr pScreen)
{
KdScreenPriv(pScreen);
i810ScreenInfo(pScreenPriv);
i810Cursor *pCurPriv = &i810s->cursor;
pCurPriv->pCursor = NULL;
}