1dfe64dd3Smacallan/* 2dfe64dd3Smacallan * XGI hardware cursor handling 3dfe64dd3Smacallan * 4dfe64dd3Smacallan * Copyright (C) 2001-2004 by Thomas Winischhofer, Vienna, Austria. 5dfe64dd3Smacallan * 6dfe64dd3Smacallan * Redistribution and use in source and binary forms, with or without 7dfe64dd3Smacallan * modification, are permitted provided that the following conditions 8dfe64dd3Smacallan * are met: 9dfe64dd3Smacallan * 1) Redistributions of source code must retain the above copyright 10dfe64dd3Smacallan * notice, this list of conditions and the following disclaimer. 11dfe64dd3Smacallan * 2) Redistributions in binary form must reproduce the above copyright 12dfe64dd3Smacallan * notice, this list of conditions and the following disclaimer in the 13dfe64dd3Smacallan * documentation and/or other materials provided with the distribution. 14dfe64dd3Smacallan * 3) The name of the author may not be used to endorse or promote products 15dfe64dd3Smacallan * derived from this software without specific prior written permission. 16dfe64dd3Smacallan * 17dfe64dd3Smacallan * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESSED OR 18dfe64dd3Smacallan * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19dfe64dd3Smacallan * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20dfe64dd3Smacallan * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21dfe64dd3Smacallan * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22dfe64dd3Smacallan * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23dfe64dd3Smacallan * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24dfe64dd3Smacallan * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25dfe64dd3Smacallan * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26dfe64dd3Smacallan * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27dfe64dd3Smacallan * 28dfe64dd3Smacallan * Author: Thomas Winischhofer <thomas@winischhofer.net> 29dfe64dd3Smacallan * 30dfe64dd3Smacallan * Idea based on code by Can-Ru Yeou, XGI Inc. 31dfe64dd3Smacallan * 32dfe64dd3Smacallan */ 33dfe64dd3Smacallan 34dfe64dd3Smacallan#ifdef HAVE_CONFIG_H 35dfe64dd3Smacallan#include "config.h" 36dfe64dd3Smacallan#endif 37dfe64dd3Smacallan 38dfe64dd3Smacallan#include "xf86.h" 39dfe64dd3Smacallan#include "xf86PciInfo.h" 40dfe64dd3Smacallan#include "cursorstr.h" 41dfe64dd3Smacallan#include "misc.h" 42dfe64dd3Smacallan#include "vgaHW.h" 43dfe64dd3Smacallan#include "xgi.h" 44dfe64dd3Smacallan#include "xgi_cursor.h" 45dfe64dd3Smacallan 46dfe64dd3Smacallanstatic int currX = 0 , currY = 0 ; 47dfe64dd3Smacallan 48dfe64dd3Smacallanstatic void XGIG1_SetCursorPosition(ScrnInfoPtr pScrn, int x, int y) ; 49dfe64dd3Smacallan 50dfe64dd3Smacallan#if X_BYTE_ORDER == X_BIG_ENDIAN 51dfe64dd3Smacallan# define BE_SWAP32(v) (lswapl(v)) 52dfe64dd3Smacallan#else 53dfe64dd3Smacallan# define BE_SWAP32(v) (v) 54dfe64dd3Smacallan#endif 55dfe64dd3Smacallan 56dfe64dd3Smacallan 57dfe64dd3Smacallan/* Helper function for Xabre to convert mono image to ARGB */ 58dfe64dd3Smacallan/* The Xabre's cursor engine for CRT2 is buggy and can't 59dfe64dd3Smacallan * handle mono cursors. We therefore convert the mono image 60dfe64dd3Smacallan * to ARGB 61dfe64dd3Smacallan */ 62dfe64dd3Smacallan 63dfe64dd3Smacallanstatic void 64dfe64dd3SmacallanVolari_ShowCursor(ScrnInfoPtr pScrn) 65dfe64dd3Smacallan{ 66dfe64dd3Smacallan XGIPtr pXGI = XGIPTR(pScrn); 67dfe64dd3Smacallan /* unsigned long cursor_addr = pXGI->CursorOffset ; */ 68dfe64dd3Smacallan unsigned long cursor_base = pXGI->CursorOffset/1024 ; 69dfe64dd3Smacallan 70dfe64dd3Smacallan /* Jong 09/19/2007; bug fixing for ??? */ 71dfe64dd3Smacallan if( pXGI->HWARGBCursor ) 72dfe64dd3Smacallan { 73dfe64dd3Smacallan xgiG2CRT1_EnableARGBHWCursor(cursor_base, 0); 74dfe64dd3Smacallan if (pXGI->VBFlags & CRT2_ENABLE) 75dfe64dd3Smacallan { 76dfe64dd3Smacallan xgiG2CRT2_EnableARGBHWCursor(cursor_base, 0); 77dfe64dd3Smacallan } 78dfe64dd3Smacallan } 79dfe64dd3Smacallan else 80dfe64dd3Smacallan { 81dfe64dd3Smacallan xgiG2CRT1_EnableHWCursor(cursor_base, 0); 82dfe64dd3Smacallan if (pXGI->VBFlags & CRT2_ENABLE) 83dfe64dd3Smacallan { 84dfe64dd3Smacallan xgiG2CRT2_EnableHWCursor(cursor_base, 0); 85dfe64dd3Smacallan } 86dfe64dd3Smacallan } 87dfe64dd3Smacallan 88dfe64dd3Smacallan XGIG1_SetCursorPosition(pScrn, currX, currY) ; 89dfe64dd3Smacallan 90dfe64dd3Smacallan /* Jong 02/05/2009; improve performance of WinBench 99 */ 91dfe64dd3Smacallan /* XGI_WaitEndRetrace(pXGI->RelIO); */ 92dfe64dd3Smacallan} 93dfe64dd3Smacallan 94dfe64dd3Smacallanstatic void 95dfe64dd3SmacallanVolari_HideCursor(ScrnInfoPtr pScrn) 96dfe64dd3Smacallan{ 97dfe64dd3Smacallan XGIPtr pXGI = XGIPTR(pScrn); 98dfe64dd3Smacallan 99dfe64dd3Smacallan PDEBUG4(ErrorF("Volari_HideCursor(pScrn)\n")); 100dfe64dd3Smacallan xgiG1CRT1_DisableHWCursor() ; 101dfe64dd3Smacallan if (pXGI->VBFlags & CRT2_ENABLE) { 102dfe64dd3Smacallan xgiG1CRT2_DisableHWCursor() ; 103dfe64dd3Smacallan } 104dfe64dd3Smacallan 105dfe64dd3Smacallan XGIG1_SetCursorPosition(pScrn, currX, currY) ; 106dfe64dd3Smacallan 107dfe64dd3Smacallan /* Jong 02/05/2009; improve performance of WinBench 99 */ 108dfe64dd3Smacallan /* XGI_WaitEndRetrace(pXGI->RelIO); */ 109dfe64dd3Smacallan} 110dfe64dd3Smacallan 111dfe64dd3Smacallanstatic void 112dfe64dd3SmacallanXGIG1_SetCursorPosition(ScrnInfoPtr pScrn, int x, int y) 113dfe64dd3Smacallan{ 114dfe64dd3Smacallan XGIPtr pXGI = XGIPTR(pScrn); 115dfe64dd3Smacallan 116dfe64dd3Smacallan unsigned char x_preset = 0; 117dfe64dd3Smacallan unsigned char y_preset = 0; 118dfe64dd3Smacallan 119dfe64dd3Smacallan currX = x ; 120dfe64dd3Smacallan currY = y ; 121dfe64dd3Smacallan 122dfe64dd3Smacallan/* ErrorF("\nHWC Set pos x:%d y:%d",x,y);*/ 123dfe64dd3Smacallan if (x < 0) { 124dfe64dd3Smacallan x_preset = (-x); 125dfe64dd3Smacallan x = 0; 126dfe64dd3Smacallan } 127dfe64dd3Smacallan if (y < 0) { 128dfe64dd3Smacallan y_preset = (-y); 129dfe64dd3Smacallan y = 0; 130dfe64dd3Smacallan } 131dfe64dd3Smacallan 132dfe64dd3Smacallan xgiG1CRT1_SetCursorPositionX(x , x_preset) ; 133dfe64dd3Smacallan xgiG1CRT1_SetCursorPositionY(y , y_preset) ; 134dfe64dd3Smacallan if (pXGI->VBFlags & CRT2_ENABLE) { 135dfe64dd3Smacallan xgiG1CRT2_SetCursorPositionX(x+13, x_preset) ; 136dfe64dd3Smacallan xgiG1CRT2_SetCursorPositionY(y, y_preset) ; 137dfe64dd3Smacallan } 138dfe64dd3Smacallan} 139dfe64dd3Smacallan 140dfe64dd3Smacallanstatic void 141dfe64dd3SmacallanVolari_SetCursorColors(ScrnInfoPtr pScrn, int bg, int fg) 142dfe64dd3Smacallan{ 143dfe64dd3Smacallan XGIPtr pXGI = XGIPTR(pScrn); 144dfe64dd3Smacallan 145dfe64dd3Smacallan xgiG1CRT1_SetCursorBGColor(bg) ; 146dfe64dd3Smacallan xgiG1CRT1_SetCursorFGColor(fg) ; 147dfe64dd3Smacallan if (pXGI->VBFlags & CRT2_ENABLE) { 148dfe64dd3Smacallan xgiG1CRT2_SetCursorBGColor(bg) ; 149dfe64dd3Smacallan xgiG1CRT2_SetCursorFGColor(fg) ; 150dfe64dd3Smacallan } 151dfe64dd3Smacallan XGIG1_SetCursorPosition(pScrn, currX, currY) ; 152dfe64dd3Smacallan} 153dfe64dd3Smacallan 154dfe64dd3Smacallanstatic void 155dfe64dd3SmacallanVolari_LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src) 156dfe64dd3Smacallan{ 157dfe64dd3Smacallan XGIPtr pXGI = XGIPTR(pScrn); 158dfe64dd3Smacallan const unsigned long cursor_base = pXGI->CursorOffset / 1024; 159dfe64dd3Smacallan unsigned char *const pCursorShape = 160dfe64dd3Smacallan pXGI->FbBase + pXGI->CursorOffset; 161dfe64dd3Smacallan 162dfe64dd3Smacallan 163dfe64dd3Smacallan memcpy(pCursorShape, src, 1024); 164dfe64dd3Smacallan 165dfe64dd3Smacallan xgiG2CRT1_SetCursorAddressPattern(cursor_base,0) ; 166dfe64dd3Smacallan if (pXGI->VBFlags & CRT2_ENABLE) { 167dfe64dd3Smacallan xgiG2CRT2_SetCursorAddressPattern(cursor_base,0) ; 168dfe64dd3Smacallan } 169dfe64dd3Smacallan XGIG1_SetCursorPosition(pScrn, currX, currY) ; 170dfe64dd3Smacallan} 171dfe64dd3Smacallan 172dfe64dd3Smacallanstatic Bool 173dfe64dd3SmacallanVolari_UseHWCursor(ScreenPtr pScreen, CursorPtr pCurs) 174dfe64dd3Smacallan{ 175dfe64dd3Smacallan ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 176dfe64dd3Smacallan DisplayModePtr mode = pScrn->currentMode; 177dfe64dd3Smacallan 178dfe64dd3Smacallan if (mode->Flags & V_INTERLACE) 179dfe64dd3Smacallan { 180dfe64dd3Smacallan return FALSE; 181dfe64dd3Smacallan } 182dfe64dd3Smacallan return TRUE; 183dfe64dd3Smacallan} 184dfe64dd3Smacallan 185dfe64dd3Smacallan/* Jong 09/19/2007; Is this required? */ 186dfe64dd3SmacallanBool 187dfe64dd3SmacallanVolari_UseHWCursorARGB(ScreenPtr pScreen, CursorPtr pCurs) 188dfe64dd3Smacallan{ 189dfe64dd3Smacallan ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 190dfe64dd3Smacallan DisplayModePtr mode = pScrn->currentMode; 191dfe64dd3Smacallan XGIPtr pXGI = XGIPTR(pScrn); 192dfe64dd3Smacallan 193dfe64dd3Smacallan if (mode->Flags & V_INTERLACE) 194dfe64dd3Smacallan { 195dfe64dd3Smacallan return FALSE; 196dfe64dd3Smacallan } 197dfe64dd3Smacallan 198dfe64dd3Smacallan /* DumpDDIName("Volari_UserHWCursorARGB()\n") ; */ 199dfe64dd3Smacallan 200dfe64dd3Smacallan return TRUE ; 201dfe64dd3Smacallan} 202dfe64dd3Smacallan 203dfe64dd3Smacallan/* Jong 09/19/2007; Is this required? */ 204dfe64dd3Smacallanstatic void 205dfe64dd3SmacallanVolari_LoadCursorARGB(ScrnInfoPtr pScrn, CursorPtr pCursor) 206dfe64dd3Smacallan{ 207dfe64dd3Smacallan XGIPtr pXGI = XGIPTR(pScrn); 208dfe64dd3Smacallan unsigned long cursor_addr = pXGI->CursorOffset ; 209dfe64dd3Smacallan unsigned long cursor_base = pXGI->CursorOffset/1024 ; 210dfe64dd3Smacallan unsigned char *pCursorShape ; 211dfe64dd3Smacallan int i , j ; CARD32 *pDest,*pSrc ; 212dfe64dd3Smacallan CursorBitsPtr pCursorBits = pCursor->bits ; 213dfe64dd3Smacallan 214dfe64dd3Smacallan 215dfe64dd3Smacallan /* DumpDDIName("Volari_LoadCursorARGB()\n") ; */ 216dfe64dd3Smacallan pXGI->HWARGBCursor = TRUE ; 217dfe64dd3Smacallan pCursorShape = pXGI->FbBase + cursor_addr ; 218dfe64dd3Smacallan 219dfe64dd3Smacallan pSrc = pCursorBits->argb ; 220dfe64dd3Smacallan 221dfe64dd3Smacallan pXGI->CurXPreset = 64-pCursorBits->width ; 222dfe64dd3Smacallan pXGI->CurYPreset = 64-pCursorBits->height ; 223dfe64dd3Smacallan 224dfe64dd3Smacallan for( i = 64 - pCursorBits->height ; i< 64 ; i++ ) 225dfe64dd3Smacallan { 226dfe64dd3Smacallan pDest = (CARD32 *)(pCursorShape + i*64*4 ) ; 227dfe64dd3Smacallan for( j = 64-pCursorBits->width ; j < 64 ; j++, pSrc++ ) 228dfe64dd3Smacallan { 229dfe64dd3Smacallan pDest[j] = *pSrc ; 230dfe64dd3Smacallan } 231dfe64dd3Smacallan } 232dfe64dd3Smacallan 233dfe64dd3Smacallan xgiG2CRT1_SetCursorAddressPattern(cursor_base,0) ; 234dfe64dd3Smacallan 235dfe64dd3Smacallan if (pXGI->VBFlags & CRT2_ENABLE) { 236dfe64dd3Smacallan xgiG2CRT2_SetCursorAddressPattern(cursor_base,0) ; 237dfe64dd3Smacallan /* xgiG1CRT2_SetCursorAddress(cursor_base) ; */ 238dfe64dd3Smacallan /* xgiG1CRT2_SetCursorPatternSelect(0) ; */ 239dfe64dd3Smacallan } 240dfe64dd3Smacallan XGIG1_SetCursorPosition(pScrn, currX, currY) ; 241dfe64dd3Smacallan PDEBUG4(vWaitCRT1VerticalRetrace(pScrn)) ; 242dfe64dd3Smacallan PDEBUG4(XGIDumpMMIO(pScrn)); 243dfe64dd3Smacallan} 244dfe64dd3Smacallan 245dfe64dd3SmacallanBool 246dfe64dd3SmacallanXGIHWCursorInit(ScreenPtr pScreen) 247dfe64dd3Smacallan{ 248dfe64dd3Smacallan ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 249dfe64dd3Smacallan XGIPtr pXGI = XGIPTR(pScrn); 250dfe64dd3Smacallan xf86CursorInfoPtr infoPtr; 251dfe64dd3Smacallan 252dfe64dd3Smacallan infoPtr = xf86CreateCursorInfoRec(); 253dfe64dd3Smacallan if(!infoPtr) return FALSE; 254dfe64dd3Smacallan 255dfe64dd3Smacallan pXGI->CursorInfoPtr = infoPtr; 256dfe64dd3Smacallan 257dfe64dd3Smacallan switch (pXGI->Chipset) { 258dfe64dd3Smacallan 259dfe64dd3Smacallan case PCI_CHIP_XGIXG40: 260dfe64dd3Smacallan case PCI_CHIP_XGIXG20: 261dfe64dd3Smacallan case PCI_CHIP_XGIXG21: 262dfe64dd3Smacallan case PCI_CHIP_XGIXG27: 263dfe64dd3Smacallan default: 264dfe64dd3Smacallan PDEBUG(ErrorF("--- HWCursorInit() \n")); 265dfe64dd3Smacallan infoPtr->MaxWidth = 64; 266dfe64dd3Smacallan infoPtr->MaxHeight = 64; 267dfe64dd3Smacallan/* infoPtr->ShowCursor = Volari_ShowCursorColor; // */ 268dfe64dd3Smacallan infoPtr->ShowCursor = Volari_ShowCursor; 269dfe64dd3Smacallan infoPtr->HideCursor = Volari_HideCursor; 270dfe64dd3Smacallan infoPtr->SetCursorPosition = XGIG1_SetCursorPosition; 271dfe64dd3Smacallan infoPtr->SetCursorColors = Volari_SetCursorColors; 272dfe64dd3Smacallan/* infoPtr->LoadCursorImage = Volari_LoadCursorImageColors; // */ 273dfe64dd3Smacallan infoPtr->LoadCursorImage = Volari_LoadCursorImage; 274dfe64dd3Smacallan infoPtr->UseHWCursor = Volari_UseHWCursor; 275dfe64dd3Smacallan/* infoPtr->RealizeCursor = XGIRealizeCursorColor ; // */ 276dfe64dd3Smacallan 277dfe64dd3Smacallan /* Jong 09/19/2007; Is this required */ 278dfe64dd3Smacallan #ifdef XGI_ARGB_CURSOR 279dfe64dd3Smacallan infoPtr->UseHWCursorARGB = Volari_UseHWCursorARGB ; 280dfe64dd3Smacallan infoPtr->LoadCursorARGB = Volari_LoadCursorARGB ; 281dfe64dd3Smacallan #endif 282dfe64dd3Smacallan 283dfe64dd3Smacallan infoPtr->Flags = 284dfe64dd3Smacallan HARDWARE_CURSOR_TRUECOLOR_AT_8BPP | 285dfe64dd3Smacallan HARDWARE_CURSOR_INVERT_MASK | 286dfe64dd3Smacallan HARDWARE_CURSOR_BIT_ORDER_MSBFIRST | 287dfe64dd3Smacallan HARDWARE_CURSOR_AND_SOURCE_WITH_MASK | 288dfe64dd3Smacallan HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK | 289dfe64dd3Smacallan HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64 ; 290dfe64dd3Smacallan break ; 291dfe64dd3Smacallan } 292dfe64dd3Smacallan 293dfe64dd3Smacallan return(xf86InitCursor(pScreen, infoPtr)); 294dfe64dd3Smacallan} 295