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