alp_hwcurs.c revision 76888252
176888252Smrg/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/cirrus/alp_hwcurs.c,v 1.4 2000/12/06 15:35:15 eich Exp $ */
276888252Smrg
376888252Smrg#ifdef HAVE_CONFIG_H
476888252Smrg#include "config.h"
576888252Smrg#endif
676888252Smrg
776888252Smrg/* (c) Itai Nahshon */
876888252Smrg
976888252Smrg#include "xf86.h"
1076888252Smrg#include "xf86_OSproc.h"
1176888252Smrg#include "compiler.h"
1276888252Smrg
1376888252Smrg#include "xf86Pci.h"
1476888252Smrg#include "xf86PciInfo.h"
1576888252Smrg
1676888252Smrg#include "vgaHW.h"
1776888252Smrg
1876888252Smrg#include "cir.h"
1976888252Smrg#define _ALP_PRIVATE_
2076888252Smrg#include "alp.h"
2176888252Smrg
2276888252Smrg#define CURSORWIDTH	pAlp->CursorWidth
2376888252Smrg#define CURSORHEIGHT	pAlp->CursorHeight
2476888252Smrg#define CURSORSIZE      (CURSORWIDTH*CURSORHEIGHT/8)
2576888252Smrg#define MAXCURSORSIZE   (64*64>>3)
2676888252Smrg
2776888252Smrgstatic void
2876888252SmrgAlpSetCursorColors(ScrnInfoPtr pScrn, int bg, int fg)
2976888252Smrg{
3076888252Smrg    const AlpPtr pAlp = ALPPTR(CIRPTR(pScrn));
3176888252Smrg	vgaHWPtr hwp = VGAHWPTR(pScrn);
3276888252Smrg#ifdef ALP_DEBUG
3376888252Smrg	ErrorF("AlpSetCursorColors\n");
3476888252Smrg#endif
3576888252Smrg	hwp->writeSeq(hwp, 0x12, pAlp->ModeReg.ExtVga[SR12]|0x02);
3676888252Smrg	hwp->writeDacWriteAddr(hwp, 0x00);
3776888252Smrg	hwp->writeDacData(hwp, 0x3f & (bg >> 18));
3876888252Smrg	hwp->writeDacData(hwp, 0x3f & (bg >> 10));
3976888252Smrg	hwp->writeDacData(hwp, 0x3f & (bg >>  2));
4076888252Smrg	hwp->writeDacWriteAddr(hwp, 0x0F);
4176888252Smrg	hwp->writeDacData(hwp, 0x3F & (fg >> 18));
4276888252Smrg	hwp->writeDacData(hwp, 0x3F & (fg >> 10));
4376888252Smrg	hwp->writeDacData(hwp, 0x3F & (fg >>  2));
4476888252Smrg	hwp->writeSeq(hwp, 0x12, pAlp->ModeReg.ExtVga[SR12]);
4576888252Smrg}
4676888252Smrg
4776888252Smrgstatic void
4876888252SmrgAlpLoadSkewedCursor(CirPtr pCir, int x, int y) {
4976888252Smrg
5076888252Smrg    const AlpPtr pAlp = ALPPTR(pCir);
5176888252Smrg
5276888252Smrg    unsigned char *memx = pAlp->HWCursorBits;
5376888252Smrg        unsigned char *CursorBits = pAlp->CursorBits;
5476888252Smrg
5576888252Smrg        unsigned char mem[2*MAXCURSORSIZE];
5676888252Smrg	unsigned char *p1, *p2;
5776888252Smrg	int i, j, m, a, b;
5876888252Smrg	Bool cur64 = (CURSORWIDTH == 64);
5976888252Smrg	int shift = (cur64? 1 : 0);
6076888252Smrg
6176888252Smrg	if (x > 0) x = 0; else x = -x;
6276888252Smrg	if (y > 0) y = 0; else y = -y;
6376888252Smrg
6476888252Smrg
6576888252Smrg	a = ((y*CURSORWIDTH<<shift)+x)>>3;
6676888252Smrg	b = x & 7;
6776888252Smrg
6876888252Smrg	/* Copy the skewed mask bits */
6976888252Smrg	p1 = mem;
7076888252Smrg	p2 = CursorBits + a;
7176888252Smrg	for (i = 0; i < (CURSORSIZE << shift)-a-1; i++) {
7276888252Smrg		*p1++ = (p2[0] << b) | (p2[1] >> (8-b));
7376888252Smrg		p2++;
7476888252Smrg	}
7576888252Smrg	/* last mask byte */
7676888252Smrg	*p1++ = (p2[0] << b);
7776888252Smrg
7876888252Smrg	/* Clear to end (bottom) of mask. */
7976888252Smrg	for (i = i+1; i < (CURSORSIZE << shift); i++)
8076888252Smrg		*p1++ = 0;
8176888252Smrg
8276888252Smrg	if (!cur64) {
8376888252Smrg	    /* Now copy the cursor bits */
8476888252Smrg	    /* p1 is already right */
8576888252Smrg	    p2 = CursorBits+CURSORSIZE+a;
8676888252Smrg	    for (i = 0; i < CURSORSIZE-a-1; i++) {
8776888252Smrg		*p1++ = (p2[0] << b) | (p2[1] >> (8-b));
8876888252Smrg		p2++;
8976888252Smrg	    }
9076888252Smrg	    /* last cursor  byte */
9176888252Smrg	    *p1++ = (p2[0] << b);
9276888252Smrg	}
9376888252Smrg
9476888252Smrg	/* Clear to end (bottom) of cursor. */
9576888252Smrg	for (i = i+1; i < CURSORSIZE; i++)
9676888252Smrg		*p1++ = 0;
9776888252Smrg
9876888252Smrg	/* Clear the right unused area of the mask
9976888252Smrg	and cyrsor bits.  */
10076888252Smrg	p2 = mem + CURSORWIDTH/8 - (x>>3) - 1;
10176888252Smrg	for (i = 0; i < 2*CURSORHEIGHT; i++) {
10276888252Smrg		m = (-1)<<(x&7);
10376888252Smrg		p1 = p2;
10476888252Smrg		p2 += CURSORWIDTH/8;
10576888252Smrg		for (j = x>>3; j >= 0; j--) {
10676888252Smrg			*p1 &= m;
10776888252Smrg			m = 0;
10876888252Smrg			p1++;
10976888252Smrg		}
11076888252Smrg	}
11176888252Smrg	memcpy(memx, mem, 2*CURSORSIZE);
11276888252Smrg}
11376888252Smrg
11476888252Smrg
11576888252Smrgstatic void
11676888252SmrgAlpSetCursorPosition(ScrnInfoPtr pScrn, int x, int y)
11776888252Smrg{
11876888252Smrg	const CirPtr pCir = CIRPTR(pScrn);
11976888252Smrg	const AlpPtr pAlp = ALPPTR(pCir);
12076888252Smrg	vgaHWPtr hwp = VGAHWPTR(pScrn);
12176888252Smrg
12276888252Smrg#if 0
12376888252Smrg#ifdef ALP_DEBUG
12476888252Smrg	ErrorF("AlpSetCursorPosition %d %d\n", x, y);
12576888252Smrg#endif
12676888252Smrg#endif
12776888252Smrg
12876888252Smrg	if (x < 0 || y < 0) {
12976888252Smrg		if (x+CURSORWIDTH <= 0 || y+CURSORHEIGHT <= 0) {
13076888252Smrg			hwp->writeSeq(hwp, 0x12, pAlp->ModeReg.ExtVga[SR12] & ~0x01);
13176888252Smrg			return;
13276888252Smrg		}
13376888252Smrg		AlpLoadSkewedCursor(pCir, x, y);
13476888252Smrg		pCir->CursorIsSkewed = TRUE;
13576888252Smrg		if (x < 0) x = 0;
13676888252Smrg		if (y < 0) y = 0;
13776888252Smrg	} else if (pCir->CursorIsSkewed) {
13876888252Smrg		memcpy(pAlp->HWCursorBits, pAlp->CursorBits, 2*CURSORSIZE);
13976888252Smrg		pCir->CursorIsSkewed = FALSE;
14076888252Smrg	}
14176888252Smrg	hwp->writeSeq(hwp, 0x12, pAlp->ModeReg.ExtVga[SR12]);
14276888252Smrg	hwp->writeSeq(hwp, ((x << 5)|0x10)&0xff, x >> 3);
14376888252Smrg	hwp->writeSeq(hwp, ((y << 5)|0x11)&0xff, y >> 3);
14476888252Smrg}
14576888252Smrg
14676888252Smrgstatic void
14776888252SmrgAlpLoadCursorImage(ScrnInfoPtr pScrn, unsigned char *bits)
14876888252Smrg{
14976888252Smrg	const AlpPtr pAlp = ALPPTR(CIRPTR(pScrn));
15076888252Smrg	vgaHWPtr hwp = VGAHWPTR(pScrn);
15176888252Smrg
15276888252Smrg#ifdef ALP_DEBUG
15376888252Smrg	ErrorF("AlpLoadCursorImage\n");
15476888252Smrg#endif
15576888252Smrg
15676888252Smrg	pAlp->CursorBits = bits;
15776888252Smrg	memcpy(pAlp->HWCursorBits, bits, 2*CURSORSIZE);
15876888252Smrg	/* this should work for both 64 and 32 bit cursors */
15976888252Smrg	pAlp->ModeReg.ExtVga[SR13] = 0x3f;
16076888252Smrg	hwp->writeSeq(hwp, 0x13, pAlp->ModeReg.ExtVga[SR13]);
16176888252Smrg}
16276888252Smrg
16376888252Smrgstatic void
16476888252SmrgAlpHideCursor(ScrnInfoPtr pScrn)
16576888252Smrg{
16676888252Smrg	AlpPtr pAlp = ALPPTR(CIRPTR(pScrn));
16776888252Smrg	vgaHWPtr hwp = VGAHWPTR(pScrn);
16876888252Smrg
16976888252Smrg#ifdef ALP_DEBUG
17076888252Smrg	ErrorF("AlpHideCursor\n");
17176888252Smrg#endif
17276888252Smrg	pAlp->ModeReg.ExtVga[SR12] &= ~0x01;
17376888252Smrg	hwp->writeSeq(hwp, 0x12, pAlp->ModeReg.ExtVga[SR12]);
17476888252Smrg}
17576888252Smrg
17676888252Smrgstatic void
17776888252SmrgAlpShowCursor(ScrnInfoPtr pScrn)
17876888252Smrg{
17976888252Smrg	AlpPtr pAlp = ALPPTR(CIRPTR(pScrn));
18076888252Smrg	vgaHWPtr hwp = VGAHWPTR(pScrn);
18176888252Smrg
18276888252Smrg#ifdef ALP_DEBUG
18376888252Smrg	ErrorF("AlpShowCursor\n");
18476888252Smrg#endif
18576888252Smrg	pAlp->ModeReg.ExtVga[SR12] |= 0x01;
18676888252Smrg	hwp->writeSeq(hwp, 0x12, pAlp->ModeReg.ExtVga[SR12]);
18776888252Smrg}
18876888252Smrg
18976888252Smrgstatic Bool
19076888252SmrgAlpUseHWCursor(ScreenPtr pScreen, CursorPtr pCurs)
19176888252Smrg{
19276888252Smrg	ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
19376888252Smrg#ifdef ALP_DEBUG
19476888252Smrg	ErrorF("AlpUseHWCursor\n");
19576888252Smrg#endif
19676888252Smrg	if (pScrn->bitsPerPixel < 8)
19776888252Smrg		return FALSE;
19876888252Smrg
19976888252Smrg	return TRUE;
20076888252Smrg}
20176888252Smrg
20276888252SmrgBool
20376888252SmrgAlpHWCursorInit(ScreenPtr pScreen, int size)
20476888252Smrg{
20576888252Smrg	ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
20676888252Smrg	const CirPtr pCir = CIRPTR(pScrn);
20776888252Smrg	const AlpPtr pAlp = ALPPTR(pCir);
20876888252Smrg
20976888252Smrg	xf86CursorInfoPtr infoPtr;
21076888252Smrg
21176888252Smrg#ifdef ALP_DEBUG
21276888252Smrg	ErrorF("AlpHWCursorInit\n");
21376888252Smrg#endif
21476888252Smrg	if (!size) return FALSE;
21576888252Smrg
21676888252Smrg	infoPtr = xf86CreateCursorInfoRec();
21776888252Smrg	if (!infoPtr) return FALSE;
21876888252Smrg
21976888252Smrg	pCir->CursorInfoRec = infoPtr;
22076888252Smrg	pCir->CursorIsSkewed = FALSE;
22176888252Smrg	pAlp->CursorBits = NULL;
22276888252Smrg
22376888252Smrg	if (size == 64)
22476888252Smrg	    CURSORWIDTH = CURSORHEIGHT = 64;
22576888252Smrg	else
22676888252Smrg	    CURSORWIDTH = CURSORHEIGHT = 32;
22776888252Smrg
22876888252Smrg	pAlp->HWCursorBits = pCir->FbBase + 1024*pScrn->videoRam - 2*CURSORSIZE;
22976888252Smrg
23076888252Smrg	infoPtr->MaxWidth = CURSORWIDTH;
23176888252Smrg	infoPtr->MaxHeight = CURSORHEIGHT;
23276888252Smrg	if (CURSORWIDTH == 64)
23376888252Smrg	    infoPtr->Flags =
23476888252Smrg#if X_BYTE_ORDER == X_LITTLE_ENDIAN
23576888252Smrg		    HARDWARE_CURSOR_BIT_ORDER_MSBFIRST |
23676888252Smrg#endif
23776888252Smrg		    HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64 |
23876888252Smrg		    HARDWARE_CURSOR_TRUECOLOR_AT_8BPP;
23976888252Smrg	else
24076888252Smrg		infoPtr->Flags =
24176888252Smrg#if X_BYTE_ORDER == X_LITTLE_ENDIAN
24276888252Smrg		    HARDWARE_CURSOR_BIT_ORDER_MSBFIRST |
24376888252Smrg#endif
24476888252Smrg		    HARDWARE_CURSOR_TRUECOLOR_AT_8BPP;
24576888252Smrg
24676888252Smrg	infoPtr->SetCursorColors = AlpSetCursorColors;
24776888252Smrg	infoPtr->SetCursorPosition = AlpSetCursorPosition;
24876888252Smrg	infoPtr->LoadCursorImage = AlpLoadCursorImage;
24976888252Smrg	infoPtr->HideCursor = AlpHideCursor;
25076888252Smrg	infoPtr->ShowCursor = AlpShowCursor;
25176888252Smrg	infoPtr->UseHWCursor = AlpUseHWCursor;
25276888252Smrg
25376888252Smrg#ifdef ALP_DEBUG
25476888252Smrg	ErrorF("AlpHWCursorInit before xf86InitCursor\n");
25576888252Smrg#endif
25676888252Smrg	xf86DrvMsg(pScrn->scrnIndex,X_INFO,"Hardware cursor: %ix%i\n",
25776888252Smrg		   CURSORWIDTH,CURSORHEIGHT);
25876888252Smrg	return(xf86InitCursor(pScreen, infoPtr));
25976888252Smrg}
26076888252Smrg
26176888252Smrg
262