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 29/* 30 * Authors: 31 * Daryll Strauss <daryll@precisioninsight.com> 32 * 33 */ 34 35#ifdef HAVE_CONFIG_H 36#include "config.h" 37#endif 38 39#include "xf86.h" 40#include "xf86_OSproc.h" 41#include "compiler.h" 42 43#include "xf86fbman.h" 44 45#include "vgaHW.h" 46#include "xf86xv.h" 47#include "i740.h" 48 49static void I740LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src); 50static void I740ShowCursor(ScrnInfoPtr pScrn); 51static void I740HideCursor(ScrnInfoPtr pScrn); 52static void I740SetCursorPosition(ScrnInfoPtr pScrn, int x, int y); 53static void I740SetCursorColors(ScrnInfoPtr pScrn, int bg, int fb); 54static Bool I740UseHWCursor(ScreenPtr pScrn, CursorPtr pCurs); 55 56Bool 57I740CursorInit(ScreenPtr pScreen) 58{ 59 ScrnInfoPtr pScrn; 60 I740Ptr pI740; 61 xf86CursorInfoPtr infoPtr; 62 FBAreaPtr fbarea; 63 64 pScrn = xf86ScreenToScrn(pScreen); 65 pI740 = I740PTR(pScrn); 66 pI740->CursorInfoRec = infoPtr = xf86CreateCursorInfoRec(); 67 if (!infoPtr) return FALSE; 68 69 infoPtr->MaxWidth = 64; 70 infoPtr->MaxHeight = 64; 71 infoPtr->Flags = HARDWARE_CURSOR_TRUECOLOR_AT_8BPP | 72 HARDWARE_CURSOR_BIT_ORDER_MSBFIRST | 73 HARDWARE_CURSOR_INVERT_MASK | 74 HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK | 75 HARDWARE_CURSOR_AND_SOURCE_WITH_MASK | 76 HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64; 77 78 infoPtr->SetCursorColors = I740SetCursorColors; 79 infoPtr->SetCursorPosition = I740SetCursorPosition; 80 infoPtr->LoadCursorImage = I740LoadCursorImage; 81 infoPtr->HideCursor = I740HideCursor; 82 infoPtr->ShowCursor = I740ShowCursor; 83 infoPtr->UseHWCursor = I740UseHWCursor; 84 85/* 86 * Allocate a region the full width and tall enough 87 * that at least 6K of video memory is consumed. 88 * Then use a 1 kilobyte piece that is 4K byte aligned 89 * within that region. KAO. 90 */ 91 fbarea = xf86AllocateOffscreenArea(pScreen, 92 pScrn->displayWidth, 93 ((6*1024)/(pScrn->displayWidth*pI740->cpp))+1, 94 0,0,0,0); 95 if (fbarea == NULL) { 96 pI740->CursorStart=0; 97 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 98 "Hardware cursor disabled due to failure allocating offscreen memory.\n"); 99 } 100 else { 101 pI740->CursorStart = ((((fbarea->box.x1 + pScrn->displayWidth * fbarea->box.y1) * pI740->cpp)+4096)&0xfff000); 102 } 103 /* 104 * Perhaps move the cursor to the beginning of the frame buffer 105 * so that it never fails? 106 */ 107 if (pI740->CursorStart>4*1024*1024) { 108 pI740->CursorStart=0; 109 xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 110 "Disabling hardware cursor due to large framebuffer\n"); 111 } 112 return xf86InitCursor(pScreen, infoPtr); 113} 114 115static Bool 116I740UseHWCursor(ScreenPtr pScreen, CursorPtr pCurs) { 117 ScrnInfoPtr pScrn; 118 I740Ptr pI740; 119 120 pScrn = xf86ScreenToScrn(pScreen); 121 pI740 = I740PTR(pScrn); 122 if (pScrn->currentMode->Flags&V_DBLSCAN) 123 return FALSE; 124 if (!pI740->CursorStart) return FALSE; 125 return TRUE; 126} 127 128static void 129I740LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src) { 130 I740Ptr pI740; 131 int x, y; 132 CARD8 *pcurs; 133 134 pI740 = I740PTR(pScrn); 135 pcurs = (CARD8 *)(pI740->FbBase + pI740->CursorStart); 136 for (y = 0; y < 64; y++) { 137 for (x = 0; x < 64 / 4; x++) { 138 *pcurs++ = *src++; 139 } 140 } 141} 142 143static void 144I740SetCursorPosition(ScrnInfoPtr pScrn, int x, int y) { 145 I740Ptr pI740; 146 int flag; 147 148 pI740 = I740PTR(pScrn); 149 if (x >= 0) flag = CURSOR_X_POS; 150 else { 151 flag = CURSOR_X_NEG; 152 x=-x; 153 } 154 pI740->writeControl(pI740, XRX, CURSOR_X_LO, x&0xFF); 155 pI740->writeControl(pI740, XRX, CURSOR_X_HI, (((x >> 8) & 0x07) | flag)); 156 157 if (y >= 0) flag = CURSOR_Y_POS; 158 else { 159 flag = CURSOR_Y_NEG; 160 y=-y; 161 } 162 pI740->writeControl(pI740, XRX, CURSOR_Y_LO, y&0xFF); 163 pI740->writeControl(pI740, XRX, CURSOR_Y_HI, (((y >> 8) & 0x07) | flag)); 164} 165 166static void 167I740ShowCursor(ScrnInfoPtr pScrn) { 168 I740Ptr pI740; 169 unsigned char tmp; 170 171 pI740 = I740PTR(pScrn); 172 pI740->writeControl(pI740, XRX, CURSOR_BASEADDR_LO, 173 (pI740->CursorStart & 0x0000F000) >> 8); 174 pI740->writeControl(pI740, XRX, CURSOR_BASEADDR_HI, 175 (pI740->CursorStart & 0x003F0000) >> 16); 176 pI740->writeControl(pI740, XRX, CURSOR_CONTROL, 177 CURSOR_ORIGIN_DISPLAY | CURSOR_MODE_64_3C); 178 179 tmp=pI740->readControl(pI740, XRX, PIXPIPE_CONFIG_0); 180 tmp |= HW_CURSOR_ENABLE; 181 pI740->writeControl(pI740, XRX, PIXPIPE_CONFIG_0, tmp); 182} 183 184static void 185I740HideCursor(ScrnInfoPtr pScrn) { 186 unsigned char tmp; 187 I740Ptr pI740; 188 189 pI740 = I740PTR(pScrn); 190 tmp=pI740->readControl(pI740, XRX, PIXPIPE_CONFIG_0); 191 tmp &= ~HW_CURSOR_ENABLE; 192 pI740->writeControl(pI740, XRX, PIXPIPE_CONFIG_0, tmp); 193} 194 195static void 196I740SetCursorColors(ScrnInfoPtr pScrn, int bg, int fg) { 197 int tmp; 198 I740Ptr pI740; 199 200 pI740 = I740PTR(pScrn); 201 tmp=pI740->readControl(pI740, XRX, PIXPIPE_CONFIG_0); 202 tmp |= EXTENDED_PALETTE; 203 pI740->writeControl(pI740, XRX, PIXPIPE_CONFIG_0, tmp); 204 205 pI740->writeStandard(pI740, DACMASK, 0xFF); 206 pI740->writeStandard(pI740, DACWX, 0x04); 207 208 pI740->writeStandard(pI740, DACDATA, (bg & 0x00FF0000) >> 16); 209 pI740->writeStandard(pI740, DACDATA, (bg & 0x0000FF00) >> 8); 210 pI740->writeStandard(pI740, DACDATA, (bg & 0x000000FF)); 211 212 pI740->writeStandard(pI740, DACDATA, (fg & 0x00FF0000) >> 16); 213 pI740->writeStandard(pI740, DACDATA, (fg & 0x0000FF00) >> 8); 214 pI740->writeStandard(pI740, DACDATA, (fg & 0x000000FF)); 215 216 tmp=pI740->readControl(pI740, XRX, PIXPIPE_CONFIG_0); 217 tmp &= ~EXTENDED_PALETTE; 218 pI740->writeControl(pI740, XRX, PIXPIPE_CONFIG_0, tmp); 219} 220 221 222 223