i740_cursor.c revision 301ea0f4
1 2/************************************************************************** 3 4Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. 5All Rights Reserved. 6 7Permission is hereby granted, free of charge, to any person obtaining a 8copy of this software and associated documentation files (the 9"Software"), to deal in the Software without restriction, including 10without limitation the rights to use, copy, modify, merge, publish, 11distribute, sub license, and/or sell copies of the Software, and to 12permit persons to whom the Software is furnished to do so, subject to 13the following conditions: 14 15The above copyright notice and this permission notice (including the 16next paragraph) shall be included in all copies or substantial portions 17of the Software. 18 19THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 20OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 22IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR 23ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 24TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 25SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 26 27**************************************************************************/ 28/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i740/i740_cursor.c,v 1.4 2000/02/23 04:47:13 martin Exp $ */ 29 30/* 31 * Authors: 32 * Daryll Strauss <daryll@precisioninsight.com> 33 * 34 */ 35 36#ifdef HAVE_CONFIG_H 37#include "config.h" 38#endif 39 40#include "xf86.h" 41#include "xf86_OSproc.h" 42#include "compiler.h" 43 44#include "xf86fbman.h" 45 46#include "vgaHW.h" 47#include "xf86xv.h" 48#include "i740.h" 49 50static void I740LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src); 51static void I740ShowCursor(ScrnInfoPtr pScrn); 52static void I740HideCursor(ScrnInfoPtr pScrn); 53static void I740SetCursorPosition(ScrnInfoPtr pScrn, int x, int y); 54static void I740SetCursorColors(ScrnInfoPtr pScrn, int bg, int fb); 55static Bool I740UseHWCursor(ScreenPtr pScrn, CursorPtr pCurs); 56 57Bool 58I740CursorInit(ScreenPtr pScreen) 59{ 60 ScrnInfoPtr pScrn; 61 I740Ptr pI740; 62 xf86CursorInfoPtr infoPtr; 63 FBAreaPtr fbarea; 64 65 pScrn = xf86Screens[pScreen->myNum]; 66 pI740 = I740PTR(pScrn); 67 pI740->CursorInfoRec = infoPtr = xf86CreateCursorInfoRec(); 68 if (!infoPtr) return FALSE; 69 70 infoPtr->MaxWidth = 64; 71 infoPtr->MaxHeight = 64; 72 infoPtr->Flags = HARDWARE_CURSOR_TRUECOLOR_AT_8BPP | 73 HARDWARE_CURSOR_BIT_ORDER_MSBFIRST | 74 HARDWARE_CURSOR_INVERT_MASK | 75 HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK | 76 HARDWARE_CURSOR_AND_SOURCE_WITH_MASK | 77 HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64; 78 79 infoPtr->SetCursorColors = I740SetCursorColors; 80 infoPtr->SetCursorPosition = I740SetCursorPosition; 81 infoPtr->LoadCursorImage = I740LoadCursorImage; 82 infoPtr->HideCursor = I740HideCursor; 83 infoPtr->ShowCursor = I740ShowCursor; 84 infoPtr->UseHWCursor = I740UseHWCursor; 85 86/* 87 * Allocate a region the full width and tall enough 88 * that at least 6K of video memory is consumed. 89 * Then use a 1 kilobyte piece that is 4K byte aligned 90 * within that region. KAO. 91 */ 92 fbarea = xf86AllocateOffscreenArea(pScreen, 93 pScrn->displayWidth, 94 ((6*1024)/(pScrn->displayWidth*pI740->cpp))+1, 95 0,0,0,0); 96 if (fbarea == NULL) { 97 pI740->CursorStart=0; 98 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 99 "Hardware cursor disabled due to failure allocating offscreen memory.\n"); 100 } 101 else { 102 pI740->CursorStart = ((((fbarea->box.x1 + pScrn->displayWidth * fbarea->box.y1) * pI740->cpp)+4096)&0xfff000); 103 } 104 /* 105 * Perhaps move the cursor to the beginning of the frame buffer 106 * so that it never fails? 107 */ 108 if (pI740->CursorStart>4*1024*1024) { 109 pI740->CursorStart=0; 110 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 111 "Disabling hardware cursor due to large framebuffer\n"); 112 } 113 return xf86InitCursor(pScreen, infoPtr); 114} 115 116static Bool 117I740UseHWCursor(ScreenPtr pScreen, CursorPtr pCurs) { 118 ScrnInfoPtr pScrn; 119 I740Ptr pI740; 120 121 pScrn = xf86Screens[pScreen->myNum]; 122 pI740 = I740PTR(pScrn); 123 if (pScrn->currentMode->Flags&V_DBLSCAN) 124 return FALSE; 125 if (!pI740->CursorStart) return FALSE; 126 return TRUE; 127} 128 129static void 130I740LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src) { 131 I740Ptr pI740; 132 int x, y; 133 CARD8 *pcurs; 134 135 pI740 = I740PTR(pScrn); 136 pcurs = (CARD8 *)(pI740->FbBase + pI740->CursorStart); 137 for (y = 0; y < 64; y++) { 138 for (x = 0; x < 64 / 4; x++) { 139 *pcurs++ = *src++; 140 } 141 } 142} 143 144static void 145I740SetCursorPosition(ScrnInfoPtr pScrn, int x, int y) { 146 I740Ptr pI740; 147 int flag; 148 149 pI740 = I740PTR(pScrn); 150 if (x >= 0) flag = CURSOR_X_POS; 151 else { 152 flag = CURSOR_X_NEG; 153 x=-x; 154 } 155 pI740->writeControl(pI740, XRX, CURSOR_X_LO, x&0xFF); 156 pI740->writeControl(pI740, XRX, CURSOR_X_HI, (((x >> 8) & 0x07) | flag)); 157 158 if (y >= 0) flag = CURSOR_Y_POS; 159 else { 160 flag = CURSOR_Y_NEG; 161 y=-y; 162 } 163 pI740->writeControl(pI740, XRX, CURSOR_Y_LO, y&0xFF); 164 pI740->writeControl(pI740, XRX, CURSOR_Y_HI, (((y >> 8) & 0x07) | flag)); 165} 166 167static void 168I740ShowCursor(ScrnInfoPtr pScrn) { 169 I740Ptr pI740; 170 unsigned char tmp; 171 172 pI740 = I740PTR(pScrn); 173 pI740->writeControl(pI740, XRX, CURSOR_BASEADDR_LO, 174 (pI740->CursorStart & 0x0000F000) >> 8); 175 pI740->writeControl(pI740, XRX, CURSOR_BASEADDR_HI, 176 (pI740->CursorStart & 0x003F0000) >> 16); 177 pI740->writeControl(pI740, XRX, CURSOR_CONTROL, 178 CURSOR_ORIGIN_DISPLAY | CURSOR_MODE_64_3C); 179 180 tmp=pI740->readControl(pI740, XRX, PIXPIPE_CONFIG_0); 181 tmp |= HW_CURSOR_ENABLE; 182 pI740->writeControl(pI740, XRX, PIXPIPE_CONFIG_0, tmp); 183} 184 185static void 186I740HideCursor(ScrnInfoPtr pScrn) { 187 unsigned char tmp; 188 I740Ptr pI740; 189 190 pI740 = I740PTR(pScrn); 191 tmp=pI740->readControl(pI740, XRX, PIXPIPE_CONFIG_0); 192 tmp &= ~HW_CURSOR_ENABLE; 193 pI740->writeControl(pI740, XRX, PIXPIPE_CONFIG_0, tmp); 194} 195 196static void 197I740SetCursorColors(ScrnInfoPtr pScrn, int bg, int fg) { 198 int tmp; 199 I740Ptr pI740; 200 201 pI740 = I740PTR(pScrn); 202 tmp=pI740->readControl(pI740, XRX, PIXPIPE_CONFIG_0); 203 tmp |= EXTENDED_PALETTE; 204 pI740->writeControl(pI740, XRX, PIXPIPE_CONFIG_0, tmp); 205 206 pI740->writeStandard(pI740, DACMASK, 0xFF); 207 pI740->writeStandard(pI740, DACWX, 0x04); 208 209 pI740->writeStandard(pI740, DACDATA, (bg & 0x00FF0000) >> 16); 210 pI740->writeStandard(pI740, DACDATA, (bg & 0x0000FF00) >> 8); 211 pI740->writeStandard(pI740, DACDATA, (bg & 0x000000FF)); 212 213 pI740->writeStandard(pI740, DACDATA, (fg & 0x00FF0000) >> 16); 214 pI740->writeStandard(pI740, DACDATA, (fg & 0x0000FF00) >> 8); 215 pI740->writeStandard(pI740, DACDATA, (fg & 0x000000FF)); 216 217 tmp=pI740->readControl(pI740, XRX, PIXPIPE_CONFIG_0); 218 tmp &= ~EXTENDED_PALETTE; 219 pI740->writeControl(pI740, XRX, PIXPIPE_CONFIG_0, tmp); 220} 221 222 223 224