/* * 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"); }