newport_cursor.c revision aee7dae4
1/* 2 * newport_cursor.c 3 */ 4/* $XFree86$ */ 5 6#ifdef HAVE_CONFIG_H 7#include "config.h" 8#endif 9 10#include "newport.h" 11#include "cursorstr.h" 12 13#include "servermd.h" 14 15#define MAX_CURS 32 16 17static void NewportShowCursor(ScrnInfoPtr pScrn); 18static void NewportHideCursor(ScrnInfoPtr pScrn); 19static void NewportSetCursorPosition(ScrnInfoPtr pScrn, int x, int y); 20static void NewportSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg); 21/* static void NewportLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *bits); */ 22static unsigned char* NewportRealizeCursor(xf86CursorInfoPtr infoPtr, CursorPtr pCurs); 23 24Bool 25NewportHWCursorInit(ScreenPtr pScreen) 26{ 27 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; 28 NewportPtr pNewport = NEWPORTPTR(pScrn); 29 NewportRegsPtr pNewportRegs = NEWPORTREGSPTR(pScrn); 30 xf86CursorInfoPtr infoPtr; 31 CARD16 tmp; 32 33 infoPtr = xf86CreateCursorInfoRec(); 34 if(!infoPtr) 35 return FALSE; 36 37 pNewport->CursorInfoRec = infoPtr; 38 infoPtr->MaxWidth = MAX_CURS; 39 infoPtr->MaxHeight = MAX_CURS; 40 infoPtr->Flags = HARDWARE_CURSOR_TRUECOLOR_AT_8BPP; 41 42 infoPtr->SetCursorColors = NewportSetCursorColors; 43 infoPtr->SetCursorPosition = NewportSetCursorPosition; 44 infoPtr->LoadCursorImage = NewportLoadCursorImage; 45 infoPtr->HideCursor = NewportHideCursor; 46 infoPtr->ShowCursor = NewportShowCursor; 47 infoPtr->RealizeCursor = NewportRealizeCursor; 48 infoPtr->UseHWCursor = NULL; 49 50 /* enable cursor funtion in shadow register */ 51 pNewport->vc2ctrl |= VC2_CTRL_ECURS; 52 /* enable glyph cursor, maximum size is 32x32x2 */ 53 pNewport->vc2ctrl &= ~( VC2_CTRL_ECG64 | VC2_CTRL_ECCURS); 54 /* setup hw cursors cmap base address */ 55 NewportBfwait(pNewportRegs); 56 pNewportRegs->set.dcbmode = (DCB_XMAP0 | R_DCB_XMAP9_PROTOCOL | 57 XM9_CRS_CURS_CMAP_MSB | NPORT_DMODE_W1 ); 58 tmp = pNewportRegs->set.dcbdata0.bytes.b3; 59#if 0 60 /* The docs say we can change base address of the cursors 61 * cmap entries, but it doesn't work. */ 62 tmp++; 63#endif 64 pNewportRegs->set.dcbmode = (DCB_XMAP0 | W_DCB_XMAP9_PROTOCOL | 65 XM9_CRS_CURS_CMAP_MSB | NPORT_DMODE_W1 ); 66 pNewportRegs->set.dcbdata0.bytes.b3 = tmp; 67 pNewport->curs_cmap_base = (tmp << 5) & 0xffe0; 68 69 return xf86InitCursor(pScreen, infoPtr); 70} 71 72 73static void NewportShowCursor(ScrnInfoPtr pScrn) 74{ 75 NewportPtr pNewport = NEWPORTPTR(pScrn); 76 NewportRegsPtr pNewportRegs = NEWPORTREGSPTR(pScrn); 77 78 pNewport->vc2ctrl |= VC2_CTRL_ECDISP; 79 NewportVc2Set( pNewportRegs, VC2_IREG_CONTROL, pNewport->vc2ctrl); 80} 81 82static void NewportHideCursor(ScrnInfoPtr pScrn) 83{ 84 NewportPtr pNewport = NEWPORTPTR(pScrn); 85 NewportRegsPtr pNewportRegs = NEWPORTREGSPTR(pScrn); 86 87 pNewport->vc2ctrl &= ~VC2_CTRL_ECDISP; 88 NewportVc2Set( pNewportRegs, VC2_IREG_CONTROL, pNewport->vc2ctrl); 89} 90 91static void NewportSetCursorPosition(ScrnInfoPtr pScrn, int x, int y) 92{ 93 CARD16 x_off; 94 NewportRegsPtr pNewportRegs = NEWPORTREGSPTR(pScrn); 95 NewportPtr pNewport = NEWPORTPTR(pScrn); 96 97 /* the docu says this should always be 31, but it isn't */ 98 x_off = 31; 99 if ( pNewport->board_rev < 6 ) 100 x_off = 21; 101 NewportVc2Set( pNewportRegs, VC2_IREG_CURSX, (CARD16) x + x_off); 102 NewportVc2Set( pNewportRegs, VC2_IREG_CURSY, (CARD16) y + 31); 103} 104 105static void NewportSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg) 106{ 107 NewportPtr pNewport = NEWPORTPTR(pScrn); 108 NewportRegsPtr pNewportRegs = NEWPORTREGSPTR(pScrn); 109 LOCO color; 110 111 color.blue = bg & 0xff; 112 color.green = (bg & 0xff00) >> 8; 113 color.red = (bg & 0xff0000) >> 16; 114 NewportCmapSetRGB( pNewportRegs, pNewport->curs_cmap_base+2, color); 115 116 color.blue = fg & 0xff; 117 color.green = (fg & 0xff00) >> 8; 118 color.red = (fg & 0xff0000) >> 16; 119 NewportCmapSetRGB( pNewportRegs, pNewport->curs_cmap_base+1, color); 120} 121 122static unsigned char* NewportRealizeCursor(xf86CursorInfoPtr infoPtr, CursorPtr pCurs) 123{ 124 int size = (infoPtr->MaxWidth * infoPtr->MaxHeight) >> 2; 125 CARD32 *mem, *SrcS, *SrcM, *DstS; 126 unsigned int i; 127 128 if (!(mem = calloc(1, size))) 129 return NULL; 130 131 SrcS = (CARD32*)pCurs->bits->source; 132 SrcM = (CARD32*)pCurs->bits->mask; 133 DstS = mem; 134 /* first color: maximum is 32*4 Bytes */ 135 for(i=0; i < pCurs->bits->height; i++) { 136 *DstS = *SrcS & *SrcM; 137 DstS++, SrcS++, SrcM++; 138 } 139 /* second color is the lower of mem: again 32*4 Bytes at most */ 140 DstS = mem + MAX_CURS; 141 SrcS = (CARD32*)pCurs->bits->source; 142 SrcM = (CARD32*)pCurs->bits->mask; 143 for(i=0; i < pCurs->bits->height; i++) { 144 *DstS = (~*SrcS) & *SrcM; 145 DstS++, SrcS++, SrcM++; 146 } 147 return (unsigned char*) mem; 148} 149 150void NewportLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *bits) 151{ 152 int i; 153 CARD16 tmp; 154 NewportRegsPtr pNewportRegs = NEWPORTREGSPTR(pScrn); 155 156 /* address of cursor data in vc2's ram */ 157 tmp = NewportVc2Get( pNewportRegs, VC2_IREG_CENTRY); 158 /* this is where we want to write to: */ 159 NewportVc2Set( pNewportRegs, VC2_IREG_RADDR, tmp); 160 pNewportRegs->set.dcbmode = (NPORT_DMODE_AVC2 | VC2_REGADDR_RAM | 161 NPORT_DMODE_W2 | VC2_PROTOCOL); 162 /* write cursor data */ 163 for (i = 0; i < ((MAX_CURS * MAX_CURS) >> 3); i++) { 164 NewportBfwait(pNewportRegs); 165 pNewportRegs->set.dcbdata0.hwords.s1 = *(unsigned short*)bits; 166 bits += sizeof(unsigned short); 167 } 168} 169 170