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