alp_hwcurs.c revision 76888252
1/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/cirrus/alp_hwcurs.c,v 1.4 2000/12/06 15:35:15 eich Exp $ */ 2 3#ifdef HAVE_CONFIG_H 4#include "config.h" 5#endif 6 7/* (c) Itai Nahshon */ 8 9#include "xf86.h" 10#include "xf86_OSproc.h" 11#include "compiler.h" 12 13#include "xf86Pci.h" 14#include "xf86PciInfo.h" 15 16#include "vgaHW.h" 17 18#include "cir.h" 19#define _ALP_PRIVATE_ 20#include "alp.h" 21 22#define CURSORWIDTH pAlp->CursorWidth 23#define CURSORHEIGHT pAlp->CursorHeight 24#define CURSORSIZE (CURSORWIDTH*CURSORHEIGHT/8) 25#define MAXCURSORSIZE (64*64>>3) 26 27static void 28AlpSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg) 29{ 30 const AlpPtr pAlp = ALPPTR(CIRPTR(pScrn)); 31 vgaHWPtr hwp = VGAHWPTR(pScrn); 32#ifdef ALP_DEBUG 33 ErrorF("AlpSetCursorColors\n"); 34#endif 35 hwp->writeSeq(hwp, 0x12, pAlp->ModeReg.ExtVga[SR12]|0x02); 36 hwp->writeDacWriteAddr(hwp, 0x00); 37 hwp->writeDacData(hwp, 0x3f & (bg >> 18)); 38 hwp->writeDacData(hwp, 0x3f & (bg >> 10)); 39 hwp->writeDacData(hwp, 0x3f & (bg >> 2)); 40 hwp->writeDacWriteAddr(hwp, 0x0F); 41 hwp->writeDacData(hwp, 0x3F & (fg >> 18)); 42 hwp->writeDacData(hwp, 0x3F & (fg >> 10)); 43 hwp->writeDacData(hwp, 0x3F & (fg >> 2)); 44 hwp->writeSeq(hwp, 0x12, pAlp->ModeReg.ExtVga[SR12]); 45} 46 47static void 48AlpLoadSkewedCursor(CirPtr pCir, int x, int y) { 49 50 const AlpPtr pAlp = ALPPTR(pCir); 51 52 unsigned char *memx = pAlp->HWCursorBits; 53 unsigned char *CursorBits = pAlp->CursorBits; 54 55 unsigned char mem[2*MAXCURSORSIZE]; 56 unsigned char *p1, *p2; 57 int i, j, m, a, b; 58 Bool cur64 = (CURSORWIDTH == 64); 59 int shift = (cur64? 1 : 0); 60 61 if (x > 0) x = 0; else x = -x; 62 if (y > 0) y = 0; else y = -y; 63 64 65 a = ((y*CURSORWIDTH<<shift)+x)>>3; 66 b = x & 7; 67 68 /* Copy the skewed mask bits */ 69 p1 = mem; 70 p2 = CursorBits + a; 71 for (i = 0; i < (CURSORSIZE << shift)-a-1; i++) { 72 *p1++ = (p2[0] << b) | (p2[1] >> (8-b)); 73 p2++; 74 } 75 /* last mask byte */ 76 *p1++ = (p2[0] << b); 77 78 /* Clear to end (bottom) of mask. */ 79 for (i = i+1; i < (CURSORSIZE << shift); i++) 80 *p1++ = 0; 81 82 if (!cur64) { 83 /* Now copy the cursor bits */ 84 /* p1 is already right */ 85 p2 = CursorBits+CURSORSIZE+a; 86 for (i = 0; i < CURSORSIZE-a-1; i++) { 87 *p1++ = (p2[0] << b) | (p2[1] >> (8-b)); 88 p2++; 89 } 90 /* last cursor byte */ 91 *p1++ = (p2[0] << b); 92 } 93 94 /* Clear to end (bottom) of cursor. */ 95 for (i = i+1; i < CURSORSIZE; i++) 96 *p1++ = 0; 97 98 /* Clear the right unused area of the mask 99 and cyrsor bits. */ 100 p2 = mem + CURSORWIDTH/8 - (x>>3) - 1; 101 for (i = 0; i < 2*CURSORHEIGHT; i++) { 102 m = (-1)<<(x&7); 103 p1 = p2; 104 p2 += CURSORWIDTH/8; 105 for (j = x>>3; j >= 0; j--) { 106 *p1 &= m; 107 m = 0; 108 p1++; 109 } 110 } 111 memcpy(memx, mem, 2*CURSORSIZE); 112} 113 114 115static void 116AlpSetCursorPosition(ScrnInfoPtr pScrn, int x, int y) 117{ 118 const CirPtr pCir = CIRPTR(pScrn); 119 const AlpPtr pAlp = ALPPTR(pCir); 120 vgaHWPtr hwp = VGAHWPTR(pScrn); 121 122#if 0 123#ifdef ALP_DEBUG 124 ErrorF("AlpSetCursorPosition %d %d\n", x, y); 125#endif 126#endif 127 128 if (x < 0 || y < 0) { 129 if (x+CURSORWIDTH <= 0 || y+CURSORHEIGHT <= 0) { 130 hwp->writeSeq(hwp, 0x12, pAlp->ModeReg.ExtVga[SR12] & ~0x01); 131 return; 132 } 133 AlpLoadSkewedCursor(pCir, x, y); 134 pCir->CursorIsSkewed = TRUE; 135 if (x < 0) x = 0; 136 if (y < 0) y = 0; 137 } else if (pCir->CursorIsSkewed) { 138 memcpy(pAlp->HWCursorBits, pAlp->CursorBits, 2*CURSORSIZE); 139 pCir->CursorIsSkewed = FALSE; 140 } 141 hwp->writeSeq(hwp, 0x12, pAlp->ModeReg.ExtVga[SR12]); 142 hwp->writeSeq(hwp, ((x << 5)|0x10)&0xff, x >> 3); 143 hwp->writeSeq(hwp, ((y << 5)|0x11)&0xff, y >> 3); 144} 145 146static void 147AlpLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *bits) 148{ 149 const AlpPtr pAlp = ALPPTR(CIRPTR(pScrn)); 150 vgaHWPtr hwp = VGAHWPTR(pScrn); 151 152#ifdef ALP_DEBUG 153 ErrorF("AlpLoadCursorImage\n"); 154#endif 155 156 pAlp->CursorBits = bits; 157 memcpy(pAlp->HWCursorBits, bits, 2*CURSORSIZE); 158 /* this should work for both 64 and 32 bit cursors */ 159 pAlp->ModeReg.ExtVga[SR13] = 0x3f; 160 hwp->writeSeq(hwp, 0x13, pAlp->ModeReg.ExtVga[SR13]); 161} 162 163static void 164AlpHideCursor(ScrnInfoPtr pScrn) 165{ 166 AlpPtr pAlp = ALPPTR(CIRPTR(pScrn)); 167 vgaHWPtr hwp = VGAHWPTR(pScrn); 168 169#ifdef ALP_DEBUG 170 ErrorF("AlpHideCursor\n"); 171#endif 172 pAlp->ModeReg.ExtVga[SR12] &= ~0x01; 173 hwp->writeSeq(hwp, 0x12, pAlp->ModeReg.ExtVga[SR12]); 174} 175 176static void 177AlpShowCursor(ScrnInfoPtr pScrn) 178{ 179 AlpPtr pAlp = ALPPTR(CIRPTR(pScrn)); 180 vgaHWPtr hwp = VGAHWPTR(pScrn); 181 182#ifdef ALP_DEBUG 183 ErrorF("AlpShowCursor\n"); 184#endif 185 pAlp->ModeReg.ExtVga[SR12] |= 0x01; 186 hwp->writeSeq(hwp, 0x12, pAlp->ModeReg.ExtVga[SR12]); 187} 188 189static Bool 190AlpUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs) 191{ 192 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 193#ifdef ALP_DEBUG 194 ErrorF("AlpUseHWCursor\n"); 195#endif 196 if (pScrn->bitsPerPixel < 8) 197 return FALSE; 198 199 return TRUE; 200} 201 202Bool 203AlpHWCursorInit(ScreenPtr pScreen, int size) 204{ 205 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 206 const CirPtr pCir = CIRPTR(pScrn); 207 const AlpPtr pAlp = ALPPTR(pCir); 208 209 xf86CursorInfoPtr infoPtr; 210 211#ifdef ALP_DEBUG 212 ErrorF("AlpHWCursorInit\n"); 213#endif 214 if (!size) return FALSE; 215 216 infoPtr = xf86CreateCursorInfoRec(); 217 if (!infoPtr) return FALSE; 218 219 pCir->CursorInfoRec = infoPtr; 220 pCir->CursorIsSkewed = FALSE; 221 pAlp->CursorBits = NULL; 222 223 if (size == 64) 224 CURSORWIDTH = CURSORHEIGHT = 64; 225 else 226 CURSORWIDTH = CURSORHEIGHT = 32; 227 228 pAlp->HWCursorBits = pCir->FbBase + 1024*pScrn->videoRam - 2*CURSORSIZE; 229 230 infoPtr->MaxWidth = CURSORWIDTH; 231 infoPtr->MaxHeight = CURSORHEIGHT; 232 if (CURSORWIDTH == 64) 233 infoPtr->Flags = 234#if X_BYTE_ORDER == X_LITTLE_ENDIAN 235 HARDWARE_CURSOR_BIT_ORDER_MSBFIRST | 236#endif 237 HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64 | 238 HARDWARE_CURSOR_TRUECOLOR_AT_8BPP; 239 else 240 infoPtr->Flags = 241#if X_BYTE_ORDER == X_LITTLE_ENDIAN 242 HARDWARE_CURSOR_BIT_ORDER_MSBFIRST | 243#endif 244 HARDWARE_CURSOR_TRUECOLOR_AT_8BPP; 245 246 infoPtr->SetCursorColors = AlpSetCursorColors; 247 infoPtr->SetCursorPosition = AlpSetCursorPosition; 248 infoPtr->LoadCursorImage = AlpLoadCursorImage; 249 infoPtr->HideCursor = AlpHideCursor; 250 infoPtr->ShowCursor = AlpShowCursor; 251 infoPtr->UseHWCursor = AlpUseHWCursor; 252 253#ifdef ALP_DEBUG 254 ErrorF("AlpHWCursorInit before xf86InitCursor\n"); 255#endif 256 xf86DrvMsg(pScrn->scrnIndex,X_INFO,"Hardware cursor: %ix%i\n", 257 CURSORWIDTH,CURSORHEIGHT); 258 return(xf86InitCursor(pScreen, infoPtr)); 259} 260 261 262