summaryrefslogtreecommitdiff
path: root/src/ast_cursor.c
diff options
context:
space:
mode:
authorAlan Coopersmith <Alan.Coopersmith@sun.com>2006-03-14 23:18:18 +0000
committerAlan Coopersmith <Alan.Coopersmith@sun.com>2006-03-14 23:18:18 +0000
commit7ce3a2ba6d211aeaa19a6841935bc50205788d62 (patch)
tree0eec6a9e5041332927fc69ca881fca589a156739 /src/ast_cursor.c
Initial code release from ASPEED Technology Inc. Bugzilla #4937
<https://bugs.freedesktop.org/show_bug.cgi?id=4937> Attachment 3686 <https://bugs.freedesktop.org/attachment.cgi?id=3686>
Diffstat (limited to 'src/ast_cursor.c')
-rw-r--r--src/ast_cursor.c376
1 files changed, 376 insertions, 0 deletions
diff --git a/src/ast_cursor.c b/src/ast_cursor.c
new file mode 100644
index 0000000..fbbce1b
--- /dev/null
+++ b/src/ast_cursor.c
@@ -0,0 +1,376 @@
+/*
+ * Copyright (c) 2005 ASPEED Technology Inc.
+ *
+ * Permission to use, copy, modify, distribute, and sell this software and its
+ * documentation for any purpose is hereby granted without fee, provided that
+ * the above copyright notice appear in all copies and that both that
+ * copyright notice and this permission notice appear in supporting
+ * documentation, and that the name of the authors not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. The authors makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THE AUTHORS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE AUTHORS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
+ * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
+ * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
+ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
+ * PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include "xf86.h"
+#include "xf86_ansic.h"
+#include "xf86_OSproc.h"
+#include "xf86Resources.h"
+#include "xf86RAC.h"
+#include "xf86cmap.h"
+#include "compiler.h"
+#include "mibstore.h"
+#include "vgaHW.h"
+#include "mipointer.h"
+#include "micmap.h"
+
+#include "fb.h"
+#include "regionstr.h"
+#include "xf86xv.h"
+#include "Xv.h"
+#include "vbe.h"
+
+#include "xf86PciInfo.h"
+#include "xf86Pci.h"
+
+/* framebuffer offscreen manager */
+#include "xf86fbman.h"
+
+/* include xaa includes */
+#include "xaa.h"
+#include "xaarop.h"
+
+/* H/W cursor support */
+#include "xf86Cursor.h"
+#include "cursorstr.h"
+
+/* Driver specific headers */
+#include "ast.h"
+
+#ifdef HWC
+/* Prototype type declaration */
+Bool ASTCursorInit(ScreenPtr pScreen);
+Bool bInitHWC(ScrnInfoPtr pScrn, ASTRecPtr pAST);
+static void ASTShowCursor(ScrnInfoPtr pScrn);
+static void ASTHideCursor(ScrnInfoPtr pScrn);
+static void ASTSetCursorPosition(ScrnInfoPtr pScrn, int x, int y);
+static void ASTSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg);
+static void ASTLoadCursorImage(ScrnInfoPtr pScrn, UCHAR *src);
+static Bool ASTUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs);
+static void ASTLoadCursorARGB(ScrnInfoPtr pScrn, CursorPtr pCurs);
+static Bool ASTUseHWCursorARGB(ScreenPtr pScreen, CursorPtr pCurs);
+
+static void ASTFireCursor(ScrnInfoPtr pScrn);
+
+Bool
+ASTCursorInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ ASTRecPtr pAST = ASTPTR(pScrn);
+ xf86CursorInfoPtr infoPtr;
+
+ infoPtr = xf86CreateCursorInfoRec();
+ if(!infoPtr) return FALSE;
+
+ pAST->HWCInfoPtr = infoPtr;
+
+ infoPtr->Flags = HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
+ HARDWARE_CURSOR_INVERT_MASK |
+ HARDWARE_CURSOR_BIT_ORDER_MSBFIRST;
+
+ infoPtr->MaxWidth = MAX_HWC_WIDTH;
+ infoPtr->MaxHeight = MAX_HWC_HEIGHT;
+ infoPtr->ShowCursor = ASTShowCursor;
+ infoPtr->HideCursor = ASTHideCursor;
+ infoPtr->SetCursorPosition = ASTSetCursorPosition;
+ infoPtr->SetCursorColors = ASTSetCursorColors;
+ infoPtr->LoadCursorImage = ASTLoadCursorImage;
+ infoPtr->UseHWCursor = ASTUseHWCursor;
+#ifdef ARGB_CURSOR
+ infoPtr->UseHWCursorARGB = ASTUseHWCursorARGB;
+ infoPtr->LoadCursorARGB = ASTLoadCursorARGB;
+#endif
+
+ return(xf86InitCursor(pScreen, infoPtr));
+
+}
+
+Bool bInitHWC(ScrnInfoPtr pScrn, ASTRecPtr pAST)
+{
+ ScreenPtr pScreen;
+
+ /* init cursor cache info */
+ /* Set HWC_NUM in Options instead */
+ /* pAST->HWCInfo.HWC_NUM = DEFAULT_HWC_NUM; */
+ pAST->HWCInfo.HWC_NUM_Next = 0;
+
+ /* allocate HWC cache */
+ if (!pAST->pHWCPtr) {
+ pScreen = screenInfo.screens[pScrn->scrnIndex];
+ pAST->pHWCPtr = xf86AllocateOffscreenLinear (pScreen, (HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM, HWC_ALIGN, NULL, NULL, NULL);
+
+ if (!pAST->pHWCPtr) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,"Allocate HWC Cache failed \n");
+ return (FALSE);
+ }
+
+ pAST->HWCInfo.ulHWCOffsetAddr = pAST->pHWCPtr->offset*((pScrn->bitsPerPixel + 1) / 8);
+ pAST->HWCInfo.pjHWCVirtualAddr = pAST->FBVirtualAddr + pAST->HWCInfo.ulHWCOffsetAddr;
+ }
+
+ return (TRUE);
+}
+
+
+static void
+ASTShowCursor(ScrnInfoPtr pScrn)
+{
+ ASTRecPtr pAST = ASTPTR(pScrn);
+ UCHAR jReg;
+
+ jReg= 0x02;
+ if (pAST->HWCInfo.cursortype ==HWC_COLOR)
+ jReg |= 0x01;
+
+ SetIndexRegMask(CRTC_PORT, 0xCB, 0xFC, jReg); /* enable mono */
+
+}
+
+static void
+ASTHideCursor(ScrnInfoPtr pScrn)
+{
+ ASTRecPtr pAST = ASTPTR(pScrn);
+
+ SetIndexRegMask(CRTC_PORT, 0xCB, 0xFC, 0x00); /* disable HWC */
+
+}
+
+static void
+ASTSetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
+{
+ ASTRecPtr pAST = ASTPTR(pScrn);
+ DisplayModePtr mode = pAST->ModePtr;
+ int x_offset, y_offset;
+
+ x_offset = pAST->HWCInfo.offset_x;
+ y_offset = pAST->HWCInfo.offset_y;
+
+ if(x < 0) {
+ x_offset = (-x) + pAST->HWCInfo.offset_x;
+ x = 0;
+ }
+
+ if(y < 0) {
+ y_offset = (-y) + pAST->HWCInfo.offset_y;
+ y = 0;
+ }
+
+ if(mode->Flags & V_DBLSCAN) y *= 2;
+
+ /* Set to Reg. */
+ SetIndexReg(CRTC_PORT, 0xC2, (UCHAR) (x_offset));
+ SetIndexReg(CRTC_PORT, 0xC3, (UCHAR) (y_offset));
+ SetIndexReg(CRTC_PORT, 0xC4, (UCHAR) (x & 0xFF));
+ SetIndexReg(CRTC_PORT, 0xC5, (UCHAR) ((x >> 8) & 0x0F));
+ SetIndexReg(CRTC_PORT, 0xC6, (UCHAR) (y & 0xFF));
+ SetIndexReg(CRTC_PORT, 0xC7, (UCHAR) ((y >> 8) & 0x07));
+
+ /* Fire HWC */
+ ASTFireCursor(pScrn);
+
+}
+
+static void
+ASTSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
+{
+ ASTRecPtr pAST = ASTPTR(pScrn);
+
+ pAST->HWCInfo.fg = (fg & 0x0F) | (((fg>>8) & 0x0F) << 4) | (((fg>>16) & 0x0F) << 8);
+ pAST->HWCInfo.bg = (bg & 0x0F) | (((bg>>8) & 0x0F) << 4) | (((bg>>16) & 0x0F) << 8);
+}
+
+static void
+ASTLoadCursorImage(ScrnInfoPtr pScrn, UCHAR *src)
+{
+ ASTRecPtr pAST = ASTPTR(pScrn);
+ int i, j, k;
+ UCHAR *pjSrcAnd, *pjSrcXor, *pjDstData;
+ ULONG ulTempDstAnd32[2], ulTempDstXor32[2], ulTempDstData32[2];
+ UCHAR jTempSrcAnd32, jTempSrcXor32;
+ ULONG ulCheckSum = 0;
+ ULONG ulPatternAddr;
+
+ /* init cursor info. */
+ pAST->HWCInfo.cursortype = HWC_MONO;
+ pAST->HWCInfo.width = (USHORT) MAX_HWC_WIDTH;
+ pAST->HWCInfo.height = (USHORT) MAX_HWC_HEIGHT;
+ pAST->HWCInfo.offset_x = MAX_HWC_WIDTH - pAST->HWCInfo.width;
+ pAST->HWCInfo.offset_y = MAX_HWC_HEIGHT - pAST->HWCInfo.height;
+
+ /* copy cursor image to cache */
+ pjSrcXor = src;
+ pjSrcAnd = src + (MAX_HWC_WIDTH*MAX_HWC_HEIGHT/8);
+ pjDstData = pAST->HWCInfo.pjHWCVirtualAddr+(HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next;
+
+ for (j = 0; j < MAX_HWC_HEIGHT; j++)
+ {
+ for (i = 0; i < (MAX_HWC_WIDTH/8); i++ )
+ {
+ for (k=7; k>0; k-=2)
+ {
+ jTempSrcAnd32 = *((UCHAR *) pjSrcAnd);
+ jTempSrcXor32 = *((UCHAR *) pjSrcXor);
+ ulTempDstAnd32[0] = ((jTempSrcAnd32 >> k) & 0x01) ? 0x00008000L:0x00L;
+ ulTempDstXor32[0] = ((jTempSrcXor32 >> k) & 0x01) ? 0x00004000L:0x00L;
+ ulTempDstData32[0] = ((jTempSrcXor32 >> k) & 0x01) ? pAST->HWCInfo.fg:pAST->HWCInfo.bg;
+ ulTempDstAnd32[1] = ((jTempSrcAnd32 >> (k-1)) & 0x01) ? 0x80000000L:0x00L;
+ ulTempDstXor32[1] = ((jTempSrcXor32 >> (k-1)) & 0x01) ? 0x40000000L:0x00L;
+ ulTempDstData32[1] = ((jTempSrcXor32 >> (k-1)) & 0x01) ? (pAST->HWCInfo.fg << 16):(pAST->HWCInfo.bg << 16);
+ *((ULONG *) pjDstData) = ulTempDstAnd32[0] | ulTempDstXor32[0] | ulTempDstData32[0] | ulTempDstAnd32[1] | ulTempDstXor32[1] | ulTempDstData32[1];
+ ulCheckSum += *((ULONG *) pjDstData);
+ pjDstData += 4;
+
+ }
+ pjSrcAnd ++;
+ pjSrcXor ++;
+
+ }
+
+ }
+
+ /* Write Checksum as signature */
+ pjDstData = (UCHAR *) pAST->HWCInfo.pjHWCVirtualAddr + (HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next + HWC_SIZE;
+ *((ULONG *) pjDstData) = ulCheckSum;
+
+ /* set pattern offset */
+ ulPatternAddr = ((pAST->HWCInfo.ulHWCOffsetAddr+(HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next) >> 3);
+ SetIndexReg(CRTC_PORT, 0xC8, (UCHAR) (ulPatternAddr & 0xFF));
+ SetIndexReg(CRTC_PORT, 0xC9, (UCHAR) ((ulPatternAddr >> 8) & 0xFF));
+ SetIndexReg(CRTC_PORT, 0xCA, (UCHAR) ((ulPatternAddr >> 16) & 0xFF));
+
+ /* update HWC_NUM_Next */
+ pAST->HWCInfo.HWC_NUM_Next = (pAST->HWCInfo.HWC_NUM_Next+1) % pAST->HWCInfo.HWC_NUM;
+
+}
+
+static Bool
+ASTUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs)
+{
+ return TRUE;
+}
+
+static void
+ASTLoadCursorARGB(ScrnInfoPtr pScrn, CursorPtr pCurs)
+{
+ ASTRecPtr pAST = ASTPTR(pScrn);
+
+ UCHAR *pjDstXor, *pjSrcXor;
+ ULONG i, j, ulSrcWidth, ulSrcHeight;
+ ULONG ulPerPixelCopy, ulTwoPixelCopy;
+ LONG lAlphaDstDelta, lLastAlphaDstDelta;
+ union
+ {
+ ULONG ul;
+ UCHAR b[4];
+ } ulSrcData32[2], ulData32;
+ union
+ {
+ USHORT us;
+ UCHAR b[2];
+ } usData16;
+ ULONG ulCheckSum = 0;
+ ULONG ulPatternAddr;
+
+ /* init cursor info. */
+ pAST->HWCInfo.cursortype = HWC_COLOR;
+ pAST->HWCInfo.width = pCurs->bits->width;
+ pAST->HWCInfo.height = pCurs->bits->height;
+ pAST->HWCInfo.offset_x = MAX_HWC_WIDTH - pAST->HWCInfo.width;
+ pAST->HWCInfo.offset_y = MAX_HWC_HEIGHT - pAST->HWCInfo.height;
+
+ /* copy cursor image to cache */
+ ulSrcWidth = pAST->HWCInfo.width;
+ ulSrcHeight = pAST->HWCInfo.height;
+
+ lAlphaDstDelta = MAX_HWC_WIDTH << 1;
+ lLastAlphaDstDelta = lAlphaDstDelta - (ulSrcWidth << 1);
+
+ pjSrcXor = (UCHAR *) pCurs->bits->argb;;
+ pjDstXor = (UCHAR *) pAST->HWCInfo.pjHWCVirtualAddr + (HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next
+ + lLastAlphaDstDelta + (MAX_HWC_HEIGHT - ulSrcHeight) * lAlphaDstDelta;
+
+ ulPerPixelCopy = ulSrcWidth & 1;
+ ulTwoPixelCopy = ulSrcWidth >> 1;
+
+ for (j = 0; j < ulSrcHeight; j++)
+ {
+
+ for (i = 0; i < ulTwoPixelCopy; i++ )
+ {
+ ulSrcData32[0].ul = *((ULONG *) pjSrcXor) & 0xF0F0F0F0;
+ ulSrcData32[1].ul = *((ULONG *) (pjSrcXor+4)) & 0xF0F0F0F0;
+ ulData32.b[0] = ulSrcData32[0].b[1] | (ulSrcData32[0].b[0] >> 4);
+ ulData32.b[1] = ulSrcData32[0].b[3] | (ulSrcData32[0].b[2] >> 4);
+ ulData32.b[2] = ulSrcData32[1].b[1] | (ulSrcData32[1].b[0] >> 4);
+ ulData32.b[3] = ulSrcData32[1].b[3] | (ulSrcData32[1].b[2] >> 4);
+ *((ULONG *) pjDstXor) = ulData32.ul;
+ ulCheckSum += (ULONG) ulData32.ul;
+ pjDstXor += 4;
+ pjSrcXor += 8;
+ }
+
+ for (i = 0; i < ulPerPixelCopy; i++ )
+ {
+ ulSrcData32[0].ul = *((ULONG *) pjSrcXor) & 0xF0F0F0F0;
+ usData16.b[0] = ulSrcData32[0].b[1] | (ulSrcData32[0].b[0] >> 4);
+ usData16.b[1] = ulSrcData32[0].b[3] | (ulSrcData32[0].b[2] >> 4);
+ *((USHORT *) pjDstXor) = usData16.us;
+ ulCheckSum += (ULONG) usData16.us;
+ pjDstXor += 2;
+ pjSrcXor += 4;
+ }
+
+ /* Point to next source and dest scans */
+ pjDstXor += lLastAlphaDstDelta;
+
+ } /* end of for-loop */
+
+ /* Write Checksum as signature */
+ pjDstXor = (UCHAR *) pAST->HWCInfo.pjHWCVirtualAddr + (HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next + HWC_SIZE;
+ *((ULONG *) pjDstXor) = ulCheckSum;
+
+ /* set pattern offset */
+ ulPatternAddr = ((pAST->HWCInfo.ulHWCOffsetAddr +(HWC_SIZE+HWC_SIGNATURE_SIZE)*pAST->HWCInfo.HWC_NUM_Next) >> 3);
+ SetIndexReg(CRTC_PORT, 0xC8, (UCHAR) (ulPatternAddr & 0xFF));
+ SetIndexReg(CRTC_PORT, 0xC9, (UCHAR) ((ulPatternAddr >> 8) & 0xFF));
+ SetIndexReg(CRTC_PORT, 0xCA, (UCHAR) ((ulPatternAddr >> 16) & 0xFF));
+
+ /* update HWC_NUM_Next */
+ pAST->HWCInfo.HWC_NUM_Next = (pAST->HWCInfo.HWC_NUM_Next+1) % pAST->HWCInfo.HWC_NUM;
+
+}
+
+static Bool
+ASTUseHWCursorARGB(ScreenPtr pScreen, CursorPtr pCurs)
+{
+ return TRUE;
+}
+
+static void
+ASTFireCursor(ScrnInfoPtr pScrn)
+{
+ ASTRecPtr pAST = ASTPTR(pScrn);
+
+ SetIndexRegMask(CRTC_PORT, 0xCB, 0xFF, 0x00); /* dummp write to fire HWC */
+
+}
+
+#endif /* End of HWC */