#include "xf86.h"
#include "xf86_OSproc.h"
#include "xf86Resources.h"
#include "xf86_ansic.h"
#include "xf86PciInfo.h"
#include "xf86Pci.h"
#include "shadowfb.h"
#include "servermd.h"
#include "smi.h"
void SMI_RefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
{
SMIPtr pSmi = SMIPTR(pScrn);
int width, height, srcX, srcY, destX, destY;
ENTER_PROC("SMI_RefreshArea");
if (pSmi->polyLines)
{
pSmi->polyLines = FALSE;
return;
}
if (pSmi->rotate)
{
WaitIdleEmpty();
WRITE_DPR(pSmi, 0x10, pSmi->ShadowPitch);
WRITE_DPR(pSmi, 0x3C, pSmi->ShadowPitch);
WRITE_DPR(pSmi, 0x44, pSmi->FBOffset >> 3);
}
if (pSmi->ClipTurnedOn)
{
WaitQueue(1);
WRITE_DPR(pSmi, 0x2C, pSmi->ScissorsLeft);
pSmi->ClipTurnedOn = FALSE;
}
while (num--)
{
srcX = pbox->x1;
srcY = pbox->y1;
width = pbox->x2 - srcX;
height = pbox->y2 - srcY;
DEBUG((VERBLEV, "x=%d y=%d w=%d h=%d\n", srcX, srcY, width, height));
if ((width > 0) && (height > 0))
{
switch (pSmi->rotate)
{
case SMI_ROTATE_CW:
destX = pSmi->ShadowHeight - srcY - 1;
destY = srcX;
WaitQueue(4);
WRITE_DPR(pSmi, 0x00, (srcX << 16) + srcY);
WRITE_DPR(pSmi, 0x04, (destX << 16) + destY);
WRITE_DPR(pSmi, 0x08, (width << 16) + height);
WRITE_DPR(pSmi, 0x0C, 0xCC | SMI_ROTATE_BLT |
SMI_ROTATE_CW | SMI_START_ENGINE);
break;
case SMI_ROTATE_CCW:
destX = srcY;
destY = pSmi->ShadowWidth - srcX - 1;
WaitQueue(4);
WRITE_DPR(pSmi, 0x00, (srcX << 16) + srcY);
WRITE_DPR(pSmi, 0x04, (destX << 16) + destY);
WRITE_DPR(pSmi, 0x08, (width << 16) + height);
WRITE_DPR(pSmi, 0x0C, 0xCC | SMI_ROTATE_BLT |
SMI_ROTATE_CCW | SMI_START_ENGINE);
break;
default:
if (pScrn->bitsPerPixel == 24)
{
srcX *= 3;
width *= 3;
if (pSmi->Chipset == SMI_LYNX)
{
srcY *= 3;
}
}
WaitQueue(4);
WRITE_DPR(pSmi, 0x00, (srcX << 16) + srcY);
WRITE_DPR(pSmi, 0x04, (srcX << 16) + srcY);
WRITE_DPR(pSmi, 0x08, (width << 16) + height);
WRITE_DPR(pSmi, 0x0C, SMI_BITBLT + SMI_START_ENGINE + 0xCC);
break;
}
}
pbox++;
}
if (pSmi->rotate)
{
WaitIdleEmpty();
WRITE_DPR(pSmi, 0x10, (pSmi->Stride << 16) | pSmi->Stride);
WRITE_DPR(pSmi, 0x3C, (pSmi->Stride << 16) | pSmi->Stride);
WRITE_DPR(pSmi, 0x44, 0);
}
LEAVE_PROC("SMI_RefreshArea");
}
void SMI_RefreshArea730(ScrnInfoPtr pScrn, int num, BoxPtr pbox)
{
SMIPtr pSmi = SMIPTR(pScrn);
int width, height, srcX, srcY, destX, destY;
int maxPixels, tempWidth;
ENTER_PROC("SMI_RefreshArea730");
if (pSmi->polyLines)
{
pSmi->polyLines = FALSE;
return;
}
if (pSmi->rotate)
{
WaitIdleEmpty();
WRITE_DPR(pSmi, 0x10, pSmi->ShadowPitch);
WRITE_DPR(pSmi, 0x3C, pSmi->ShadowPitch);
WRITE_DPR(pSmi, 0x44, pSmi->FBOffset >> 3);
}
if (pSmi->ClipTurnedOn)
{
WaitQueue(1);
WRITE_DPR(pSmi, 0x2C, pSmi->ScissorsLeft);
pSmi->ClipTurnedOn = FALSE;
}
maxPixels = 1280 / pScrn->bitsPerPixel;
while (num--)
{
srcX = pbox->x1;
srcY = pbox->y1;
width = pbox->x2 - srcX;
height = pbox->y2 - srcY;
DEBUG((VERBLEV, "x=%d y=%d w=%d h=%d\n", srcX, srcY, width, height));
if ((width > 0) && (height > 0))
{
switch (pSmi->rotate)
{
case SMI_ROTATE_CW:
destX = pSmi->ShadowHeight - srcY - 1;
destY = srcX;
for (tempWidth=width; tempWidth>0;)
{
if (width>maxPixels)
width = maxPixels;
WaitQueue(4);
WRITE_DPR(pSmi, 0x00, (srcX << 16) + srcY);
WRITE_DPR(pSmi, 0x04, (destX << 16) + destY);
WRITE_DPR(pSmi, 0x08, (width << 16) + height);
WRITE_DPR(pSmi, 0x0C, 0xCC | SMI_ROTATE_BLT |
SMI_ROTATE_CW | SMI_START_ENGINE);
destY += maxPixels;
srcX += maxPixels;
tempWidth -= maxPixels;
width = tempWidth;
}
break;
case SMI_ROTATE_CCW:
destX = srcY;
destY = pSmi->ShadowWidth - srcX - 1;
for (tempWidth=width; tempWidth>0;)
{
if (width>maxPixels)
width = maxPixels;
WaitQueue(4);
WRITE_DPR(pSmi, 0x00, (srcX << 16) + srcY);
WRITE_DPR(pSmi, 0x04, (destX << 16) + destY);
WRITE_DPR(pSmi, 0x08, (width << 16) + height);
WRITE_DPR(pSmi, 0x0C, 0xCC | SMI_ROTATE_BLT |
SMI_ROTATE_CCW | SMI_START_ENGINE);
destY -= maxPixels;
srcX += maxPixels;
tempWidth -= maxPixels;
width = tempWidth;
}
break;
default:
if (pScrn->bitsPerPixel == 24)
{
srcX *= 3;
width *= 3;
if (pSmi->Chipset == SMI_LYNX)
{
srcY *= 3;
}
}
WaitQueue(4);
WRITE_DPR(pSmi, 0x00, (srcX << 16) + srcY);
WRITE_DPR(pSmi, 0x04, (srcX << 16) + srcY);
WRITE_DPR(pSmi, 0x08, (width << 16) + height);
WRITE_DPR(pSmi, 0x0C, SMI_BITBLT + SMI_START_ENGINE + 0xCC);
break;
}
}
pbox++;
}
if (pSmi->rotate)
{
WaitIdleEmpty();
WRITE_DPR(pSmi, 0x10, (pSmi->Stride << 16) | pSmi->Stride);
WRITE_DPR(pSmi, 0x3C, (pSmi->Stride << 16) | pSmi->Stride);
WRITE_DPR(pSmi, 0x44, 0);
}
LEAVE_PROC("SMI_RefreshArea730");
}
void SMI_PointerMoved(int index, int x, int y)
{
ScrnInfoPtr pScrn = xf86Screens[index];
SMIPtr pSmi = SMIPTR(pScrn);
int newX, newY;
switch (pSmi->rotate)
{
case SMI_ROTATE_CW:
newX = pScrn->pScreen->height - y - 1;
newY = x;
break;
case SMI_ROTATE_CCW:
newX = y;
newY = pScrn->pScreen->width - x - 1;
break;
default:
newX = x;
newY = y;
break;
}
(*pSmi->PointerMoved)(index, newX, newY);
}