i740_cursor.c revision 301ea0f4
1301ea0f4Smrg 2301ea0f4Smrg/************************************************************************** 3301ea0f4Smrg 4301ea0f4SmrgCopyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. 5301ea0f4SmrgAll Rights Reserved. 6301ea0f4Smrg 7301ea0f4SmrgPermission is hereby granted, free of charge, to any person obtaining a 8301ea0f4Smrgcopy of this software and associated documentation files (the 9301ea0f4Smrg"Software"), to deal in the Software without restriction, including 10301ea0f4Smrgwithout limitation the rights to use, copy, modify, merge, publish, 11301ea0f4Smrgdistribute, sub license, and/or sell copies of the Software, and to 12301ea0f4Smrgpermit persons to whom the Software is furnished to do so, subject to 13301ea0f4Smrgthe following conditions: 14301ea0f4Smrg 15301ea0f4SmrgThe above copyright notice and this permission notice (including the 16301ea0f4Smrgnext paragraph) shall be included in all copies or substantial portions 17301ea0f4Smrgof the Software. 18301ea0f4Smrg 19301ea0f4SmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 20301ea0f4SmrgOR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 21301ea0f4SmrgMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 22301ea0f4SmrgIN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR 23301ea0f4SmrgANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 24301ea0f4SmrgTORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 25301ea0f4SmrgSOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 26301ea0f4Smrg 27301ea0f4Smrg**************************************************************************/ 28301ea0f4Smrg/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/i740/i740_cursor.c,v 1.4 2000/02/23 04:47:13 martin Exp $ */ 29301ea0f4Smrg 30301ea0f4Smrg/* 31301ea0f4Smrg * Authors: 32301ea0f4Smrg * Daryll Strauss <daryll@precisioninsight.com> 33301ea0f4Smrg * 34301ea0f4Smrg */ 35301ea0f4Smrg 36301ea0f4Smrg#ifdef HAVE_CONFIG_H 37301ea0f4Smrg#include "config.h" 38301ea0f4Smrg#endif 39301ea0f4Smrg 40301ea0f4Smrg#include "xf86.h" 41301ea0f4Smrg#include "xf86_OSproc.h" 42301ea0f4Smrg#include "compiler.h" 43301ea0f4Smrg 44301ea0f4Smrg#include "xf86fbman.h" 45301ea0f4Smrg 46301ea0f4Smrg#include "vgaHW.h" 47301ea0f4Smrg#include "xf86xv.h" 48301ea0f4Smrg#include "i740.h" 49301ea0f4Smrg 50301ea0f4Smrgstatic void I740LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src); 51301ea0f4Smrgstatic void I740ShowCursor(ScrnInfoPtr pScrn); 52301ea0f4Smrgstatic void I740HideCursor(ScrnInfoPtr pScrn); 53301ea0f4Smrgstatic void I740SetCursorPosition(ScrnInfoPtr pScrn, int x, int y); 54301ea0f4Smrgstatic void I740SetCursorColors(ScrnInfoPtr pScrn, int bg, int fb); 55301ea0f4Smrgstatic Bool I740UseHWCursor(ScreenPtr pScrn, CursorPtr pCurs); 56301ea0f4Smrg 57301ea0f4SmrgBool 58301ea0f4SmrgI740CursorInit(ScreenPtr pScreen) 59301ea0f4Smrg{ 60301ea0f4Smrg ScrnInfoPtr pScrn; 61301ea0f4Smrg I740Ptr pI740; 62301ea0f4Smrg xf86CursorInfoPtr infoPtr; 63301ea0f4Smrg FBAreaPtr fbarea; 64301ea0f4Smrg 65301ea0f4Smrg pScrn = xf86Screens[pScreen->myNum]; 66301ea0f4Smrg pI740 = I740PTR(pScrn); 67301ea0f4Smrg pI740->CursorInfoRec = infoPtr = xf86CreateCursorInfoRec(); 68301ea0f4Smrg if (!infoPtr) return FALSE; 69301ea0f4Smrg 70301ea0f4Smrg infoPtr->MaxWidth = 64; 71301ea0f4Smrg infoPtr->MaxHeight = 64; 72301ea0f4Smrg infoPtr->Flags = HARDWARE_CURSOR_TRUECOLOR_AT_8BPP | 73301ea0f4Smrg HARDWARE_CURSOR_BIT_ORDER_MSBFIRST | 74301ea0f4Smrg HARDWARE_CURSOR_INVERT_MASK | 75301ea0f4Smrg HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK | 76301ea0f4Smrg HARDWARE_CURSOR_AND_SOURCE_WITH_MASK | 77301ea0f4Smrg HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64; 78301ea0f4Smrg 79301ea0f4Smrg infoPtr->SetCursorColors = I740SetCursorColors; 80301ea0f4Smrg infoPtr->SetCursorPosition = I740SetCursorPosition; 81301ea0f4Smrg infoPtr->LoadCursorImage = I740LoadCursorImage; 82301ea0f4Smrg infoPtr->HideCursor = I740HideCursor; 83301ea0f4Smrg infoPtr->ShowCursor = I740ShowCursor; 84301ea0f4Smrg infoPtr->UseHWCursor = I740UseHWCursor; 85301ea0f4Smrg 86301ea0f4Smrg/* 87301ea0f4Smrg * Allocate a region the full width and tall enough 88301ea0f4Smrg * that at least 6K of video memory is consumed. 89301ea0f4Smrg * Then use a 1 kilobyte piece that is 4K byte aligned 90301ea0f4Smrg * within that region. KAO. 91301ea0f4Smrg */ 92301ea0f4Smrg fbarea = xf86AllocateOffscreenArea(pScreen, 93301ea0f4Smrg pScrn->displayWidth, 94301ea0f4Smrg ((6*1024)/(pScrn->displayWidth*pI740->cpp))+1, 95301ea0f4Smrg 0,0,0,0); 96301ea0f4Smrg if (fbarea == NULL) { 97301ea0f4Smrg pI740->CursorStart=0; 98301ea0f4Smrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 99301ea0f4Smrg "Hardware cursor disabled due to failure allocating offscreen memory.\n"); 100301ea0f4Smrg } 101301ea0f4Smrg else { 102301ea0f4Smrg pI740->CursorStart = ((((fbarea->box.x1 + pScrn->displayWidth * fbarea->box.y1) * pI740->cpp)+4096)&0xfff000); 103301ea0f4Smrg } 104301ea0f4Smrg /* 105301ea0f4Smrg * Perhaps move the cursor to the beginning of the frame buffer 106301ea0f4Smrg * so that it never fails? 107301ea0f4Smrg */ 108301ea0f4Smrg if (pI740->CursorStart>4*1024*1024) { 109301ea0f4Smrg pI740->CursorStart=0; 110301ea0f4Smrg xf86DrvMsg(pScrn->scrnIndex, X_WARNING, 111301ea0f4Smrg "Disabling hardware cursor due to large framebuffer\n"); 112301ea0f4Smrg } 113301ea0f4Smrg return xf86InitCursor(pScreen, infoPtr); 114301ea0f4Smrg} 115301ea0f4Smrg 116301ea0f4Smrgstatic Bool 117301ea0f4SmrgI740UseHWCursor(ScreenPtr pScreen, CursorPtr pCurs) { 118301ea0f4Smrg ScrnInfoPtr pScrn; 119301ea0f4Smrg I740Ptr pI740; 120301ea0f4Smrg 121301ea0f4Smrg pScrn = xf86Screens[pScreen->myNum]; 122301ea0f4Smrg pI740 = I740PTR(pScrn); 123301ea0f4Smrg if (pScrn->currentMode->Flags&V_DBLSCAN) 124301ea0f4Smrg return FALSE; 125301ea0f4Smrg if (!pI740->CursorStart) return FALSE; 126301ea0f4Smrg return TRUE; 127301ea0f4Smrg} 128301ea0f4Smrg 129301ea0f4Smrgstatic void 130301ea0f4SmrgI740LoadCursorImage(ScrnInfoPtr pScrn, unsigned char *src) { 131301ea0f4Smrg I740Ptr pI740; 132301ea0f4Smrg int x, y; 133301ea0f4Smrg CARD8 *pcurs; 134301ea0f4Smrg 135301ea0f4Smrg pI740 = I740PTR(pScrn); 136301ea0f4Smrg pcurs = (CARD8 *)(pI740->FbBase + pI740->CursorStart); 137301ea0f4Smrg for (y = 0; y < 64; y++) { 138301ea0f4Smrg for (x = 0; x < 64 / 4; x++) { 139301ea0f4Smrg *pcurs++ = *src++; 140301ea0f4Smrg } 141301ea0f4Smrg } 142301ea0f4Smrg} 143301ea0f4Smrg 144301ea0f4Smrgstatic void 145301ea0f4SmrgI740SetCursorPosition(ScrnInfoPtr pScrn, int x, int y) { 146301ea0f4Smrg I740Ptr pI740; 147301ea0f4Smrg int flag; 148301ea0f4Smrg 149301ea0f4Smrg pI740 = I740PTR(pScrn); 150301ea0f4Smrg if (x >= 0) flag = CURSOR_X_POS; 151301ea0f4Smrg else { 152301ea0f4Smrg flag = CURSOR_X_NEG; 153301ea0f4Smrg x=-x; 154301ea0f4Smrg } 155301ea0f4Smrg pI740->writeControl(pI740, XRX, CURSOR_X_LO, x&0xFF); 156301ea0f4Smrg pI740->writeControl(pI740, XRX, CURSOR_X_HI, (((x >> 8) & 0x07) | flag)); 157301ea0f4Smrg 158301ea0f4Smrg if (y >= 0) flag = CURSOR_Y_POS; 159301ea0f4Smrg else { 160301ea0f4Smrg flag = CURSOR_Y_NEG; 161301ea0f4Smrg y=-y; 162301ea0f4Smrg } 163301ea0f4Smrg pI740->writeControl(pI740, XRX, CURSOR_Y_LO, y&0xFF); 164301ea0f4Smrg pI740->writeControl(pI740, XRX, CURSOR_Y_HI, (((y >> 8) & 0x07) | flag)); 165301ea0f4Smrg} 166301ea0f4Smrg 167301ea0f4Smrgstatic void 168301ea0f4SmrgI740ShowCursor(ScrnInfoPtr pScrn) { 169301ea0f4Smrg I740Ptr pI740; 170301ea0f4Smrg unsigned char tmp; 171301ea0f4Smrg 172301ea0f4Smrg pI740 = I740PTR(pScrn); 173301ea0f4Smrg pI740->writeControl(pI740, XRX, CURSOR_BASEADDR_LO, 174301ea0f4Smrg (pI740->CursorStart & 0x0000F000) >> 8); 175301ea0f4Smrg pI740->writeControl(pI740, XRX, CURSOR_BASEADDR_HI, 176301ea0f4Smrg (pI740->CursorStart & 0x003F0000) >> 16); 177301ea0f4Smrg pI740->writeControl(pI740, XRX, CURSOR_CONTROL, 178301ea0f4Smrg CURSOR_ORIGIN_DISPLAY | CURSOR_MODE_64_3C); 179301ea0f4Smrg 180301ea0f4Smrg tmp=pI740->readControl(pI740, XRX, PIXPIPE_CONFIG_0); 181301ea0f4Smrg tmp |= HW_CURSOR_ENABLE; 182301ea0f4Smrg pI740->writeControl(pI740, XRX, PIXPIPE_CONFIG_0, tmp); 183301ea0f4Smrg} 184301ea0f4Smrg 185301ea0f4Smrgstatic void 186301ea0f4SmrgI740HideCursor(ScrnInfoPtr pScrn) { 187301ea0f4Smrg unsigned char tmp; 188301ea0f4Smrg I740Ptr pI740; 189301ea0f4Smrg 190301ea0f4Smrg pI740 = I740PTR(pScrn); 191301ea0f4Smrg tmp=pI740->readControl(pI740, XRX, PIXPIPE_CONFIG_0); 192301ea0f4Smrg tmp &= ~HW_CURSOR_ENABLE; 193301ea0f4Smrg pI740->writeControl(pI740, XRX, PIXPIPE_CONFIG_0, tmp); 194301ea0f4Smrg} 195301ea0f4Smrg 196301ea0f4Smrgstatic void 197301ea0f4SmrgI740SetCursorColors(ScrnInfoPtr pScrn, int bg, int fg) { 198301ea0f4Smrg int tmp; 199301ea0f4Smrg I740Ptr pI740; 200301ea0f4Smrg 201301ea0f4Smrg pI740 = I740PTR(pScrn); 202301ea0f4Smrg tmp=pI740->readControl(pI740, XRX, PIXPIPE_CONFIG_0); 203301ea0f4Smrg tmp |= EXTENDED_PALETTE; 204301ea0f4Smrg pI740->writeControl(pI740, XRX, PIXPIPE_CONFIG_0, tmp); 205301ea0f4Smrg 206301ea0f4Smrg pI740->writeStandard(pI740, DACMASK, 0xFF); 207301ea0f4Smrg pI740->writeStandard(pI740, DACWX, 0x04); 208301ea0f4Smrg 209301ea0f4Smrg pI740->writeStandard(pI740, DACDATA, (bg & 0x00FF0000) >> 16); 210301ea0f4Smrg pI740->writeStandard(pI740, DACDATA, (bg & 0x0000FF00) >> 8); 211301ea0f4Smrg pI740->writeStandard(pI740, DACDATA, (bg & 0x000000FF)); 212301ea0f4Smrg 213301ea0f4Smrg pI740->writeStandard(pI740, DACDATA, (fg & 0x00FF0000) >> 16); 214301ea0f4Smrg pI740->writeStandard(pI740, DACDATA, (fg & 0x0000FF00) >> 8); 215301ea0f4Smrg pI740->writeStandard(pI740, DACDATA, (fg & 0x000000FF)); 216301ea0f4Smrg 217301ea0f4Smrg tmp=pI740->readControl(pI740, XRX, PIXPIPE_CONFIG_0); 218301ea0f4Smrg tmp &= ~EXTENDED_PALETTE; 219301ea0f4Smrg pI740->writeControl(pI740, XRX, PIXPIPE_CONFIG_0, tmp); 220301ea0f4Smrg} 221301ea0f4Smrg 222301ea0f4Smrg 223301ea0f4Smrg 224