/* $XFree86$ */ /* * 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 * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS 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 UniChrom * ************************************************************************/ #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); /* * Read/write to the DAC via MMIO */ #define inCRReg(reg) (VGAHWPTR(pScrn))->readCrtc(VGAHWPTR(pScrn), reg) #define outCRReg(reg, val) (VGAHWPTR(pScrn))->writeCrtc(VGAHWPTR(pScrn), reg, val) #define inStatus1() (VGAHWPTR(pScrn))->readST01(VGAHWPTR(pScrn)) #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; WaitIdle(); 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); }