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