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