summaryrefslogtreecommitdiff
path: root/trunk/src/via_cursor.c
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/src/via_cursor.c')
-rw-r--r--trunk/src/via_cursor.c223
1 files changed, 223 insertions, 0 deletions
diff --git a/trunk/src/via_cursor.c b/trunk/src/via_cursor.c
new file mode 100644
index 000000000000..74b7c2180fa7
--- /dev/null
+++ b/trunk/src/via_cursor.c
@@ -0,0 +1,223 @@
+/*
+ * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
+ * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/*************************************************************************
+ *
+ * File: via_cursor.c
+ * Content: Hardware cursor support for VIA/S3G UniChrome
+ *
+ ************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "via.h"
+#include "via_driver.h"
+
+static void VIALoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src);
+static void VIASetCursorPosition(ScrnInfoPtr pScrn, int x, int y);
+static void VIASetCursorColors(ScrnInfoPtr pScrn, int bg, int fg);
+
+#define MAX_CURS 32
+
+Bool
+VIAHWCursorInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ VIAPtr pVia = VIAPTR(pScrn);
+ xf86CursorInfoPtr infoPtr;
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "VIAHWCursorInit\n"));
+ infoPtr = xf86CreateCursorInfoRec();
+ if (!infoPtr)
+ return FALSE;
+
+ pVia->CursorInfoRec = infoPtr;
+
+ infoPtr->MaxWidth = MAX_CURS;
+ infoPtr->MaxHeight = MAX_CURS;
+ infoPtr->Flags = (HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_32 |
+ HARDWARE_CURSOR_AND_SOURCE_WITH_MASK |
+ /*HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK | */
+ HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
+ HARDWARE_CURSOR_INVERT_MASK |
+ HARDWARE_CURSOR_BIT_ORDER_MSBFIRST |
+ 0);
+
+ infoPtr->SetCursorColors = VIASetCursorColors;
+ infoPtr->SetCursorPosition = VIASetCursorPosition;
+ infoPtr->LoadCursorImage = VIALoadCursorImage;
+ infoPtr->HideCursor = VIAHideCursor;
+ infoPtr->ShowCursor = VIAShowCursor;
+ infoPtr->UseHWCursor = NULL;
+
+ if (!pVia->CursorStart) {
+ pVia->CursorStart = pVia->FBFreeEnd - VIA_CURSOR_SIZE;
+ pVia->FBFreeEnd -= VIA_CURSOR_SIZE;
+ }
+
+ /* Set cursor location in frame buffer. */
+ VIASETREG(VIA_REG_CURSOR_MODE, pVia->CursorStart);
+
+ return xf86InitCursor(pScreen, infoPtr);
+}
+
+
+void
+VIAShowCursor(ScrnInfoPtr pScrn)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+ CARD32 dwCursorMode;
+
+ dwCursorMode = VIAGETREG(VIA_REG_CURSOR_MODE);
+
+ /* Turn on hardware cursor. */
+ VIASETREG(VIA_REG_CURSOR_MODE, dwCursorMode | 0x3);
+}
+
+
+void
+VIAHideCursor(ScrnInfoPtr pScrn)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+ CARD32 dwCursorMode;
+
+ dwCursorMode = VIAGETREG(VIA_REG_CURSOR_MODE);
+
+ /* Turn cursor off. */
+ VIASETREG(VIA_REG_CURSOR_MODE, dwCursorMode & 0xFFFFFFFE);
+}
+
+
+static void
+VIALoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+ CARD32 dwCursorMode;
+
+ viaAccelSync(pScrn);
+
+ dwCursorMode = VIAGETREG(VIA_REG_CURSOR_MODE);
+
+ /* Turn cursor off. */
+ VIASETREG(VIA_REG_CURSOR_MODE, dwCursorMode & 0xFFFFFFFE);
+
+ /* Upload the cursor image to the frame buffer. */
+ memcpy(pVia->FBBase + pVia->CursorStart, src, MAX_CURS * MAX_CURS / 8 * 2);
+
+ /* Restore cursor status */
+ VIASETREG(VIA_REG_CURSOR_MODE, dwCursorMode);
+}
+
+static void
+VIASetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+ VIABIOSInfoPtr pBIOSInfo = pVia->pBIOSInfo;
+ unsigned char xoff, yoff;
+ CARD32 dwCursorMode;
+
+ if (x < 0) {
+ xoff = ((-x) & 0xFE);
+ x = 0;
+ } else {
+ xoff = 0;
+ }
+
+ if (y < 0) {
+ yoff = ((-y) & 0xFE);
+ y = 0;
+ } else {
+ yoff = 0;
+ /* LCD Expand Mode Cursor Y Position Re-Calculated */
+ if (pBIOSInfo->scaleY) {
+ y = (int)(((pBIOSInfo->panelY * y) + (pBIOSInfo->resY >> 1))
+ / pBIOSInfo->resY);
+ }
+ }
+
+ /* Hide cursor before set cursor position in order to avoid ghost cursor
+ * image when directly set cursor position. It should be a HW bug but
+ * we can use patch by SW. */
+ dwCursorMode = VIAGETREG(VIA_REG_CURSOR_MODE);
+
+ /* Turn cursor off. */
+ VIASETREG(VIA_REG_CURSOR_MODE, dwCursorMode & 0xFFFFFFFE);
+
+ VIASETREG(VIA_REG_CURSOR_ORG, ((xoff << 16) | (yoff & 0x003f)));
+ VIASETREG(VIA_REG_CURSOR_POS, ((x << 16) | (y & 0x07ff)));
+
+ /* Restore cursor status */
+ VIASETREG(VIA_REG_CURSOR_MODE, dwCursorMode);
+}
+
+
+static void
+VIASetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+
+ VIASETREG(VIA_REG_CURSOR_FG, fg);
+ VIASETREG(VIA_REG_CURSOR_BG, bg);
+}
+
+void
+ViaCursorStore(ScrnInfoPtr pScrn)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaCursorStore\n"));
+
+ if (pVia->CursorImage) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "ViaCursorStore: stale image left.\n");
+ xfree(pVia->CursorImage);
+ }
+
+ pVia->CursorImage = xcalloc(1, 0x1000);
+ memcpy(pVia->CursorImage, pVia->FBBase + pVia->CursorStart, 0x1000);
+ pVia->CursorFG = (CARD32) VIAGETREG(VIA_REG_CURSOR_FG);
+ pVia->CursorBG = (CARD32) VIAGETREG(VIA_REG_CURSOR_BG);
+ pVia->CursorMC = (CARD32) VIAGETREG(VIA_REG_CURSOR_MODE);
+}
+
+void
+ViaCursorRestore(ScrnInfoPtr pScrn)
+{
+ VIAPtr pVia = VIAPTR(pScrn);
+
+ DEBUG(xf86DrvMsg(pScrn->scrnIndex, X_INFO, "ViaCursorRestore\n"));
+
+ if (pVia->CursorImage) {
+ memcpy(pVia->FBBase + pVia->CursorStart, pVia->CursorImage, 0x1000);
+ VIASETREG(VIA_REG_CURSOR_FG, pVia->CursorFG);
+ VIASETREG(VIA_REG_CURSOR_BG, pVia->CursorBG);
+ VIASETREG(VIA_REG_CURSOR_MODE, pVia->CursorMC);
+ xfree(pVia->CursorImage);
+ pVia->CursorImage = NULL;
+ } else
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "ViaCursorRestore: No cursor image stored.\n");
+}