xref: /haiku/src/add-ons/accelerants/ati/rage128_cursor.cpp (revision 80829ec813241c9a702a45e39929286f13c55093)
1 /*
2 	Haiku ATI video driver adapted from the X.org ATI driver.
3 
4 	Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario,
5 						 Precision Insight, Inc., Cedar Park, Texas, and
6 						 VA Linux Systems Inc., Fremont, California.
7 
8 	Copyright 2009 Haiku, Inc.  All rights reserved.
9 	Distributed under the terms of the MIT license.
10 
11 	Authors:
12 	Gerald Zajac 2009
13 */
14 
15 
16 #include "accelerant.h"
17 #include "rage128.h"
18 
19 
20 
21 void
Rage128_ShowCursor(bool bShow)22 Rage128_ShowCursor(bool bShow)
23 {
24 	// Turn cursor on/off.
25 
26    	OUTREGM(R128_CRTC_GEN_CNTL, bShow ? R128_CRTC_CUR_EN : 0, R128_CRTC_CUR_EN);
27 }
28 
29 
30 void
Rage128_SetCursorPosition(int x,int y)31 Rage128_SetCursorPosition(int x, int y)
32 {
33 	SharedInfo& si = *gInfo.sharedInfo;
34 
35 	// xOffset & yOffset are used for displaying partial cursors on screen edges.
36 
37 	uint8 xOffset = 0;
38 	uint8 yOffset = 0;
39 
40 	if (x < 0) {
41 		xOffset = (( -x) & 0xFE);
42 		x = 0;
43 	}
44 
45 	if (y < 0) {
46 		yOffset = (( -y) & 0xFE);
47 		y = 0;
48 	}
49 
50 	OUTREG(R128_CUR_HORZ_VERT_OFF,  R128_CUR_LOCK | (xOffset << 16) | yOffset);
51 	OUTREG(R128_CUR_HORZ_VERT_POSN, R128_CUR_LOCK | (x << 16) | y);
52 	OUTREG(R128_CUR_OFFSET, si.cursorOffset + yOffset * 16);
53 }
54 
55 
56 bool
Rage128_LoadCursorImage(int width,int height,uint8 * andMask,uint8 * xorMask)57 Rage128_LoadCursorImage(int width, int height, uint8* andMask, uint8* xorMask)
58 {
59 	SharedInfo& si = *gInfo.sharedInfo;
60 
61 	if (andMask == NULL || xorMask == NULL)
62 		return false;
63 
64 	// Initialize the hardware cursor as completely transparent.
65 
66 	uint32* fbCursor32 = (uint32*)((addr_t)si.videoMemAddr + si.cursorOffset);
67 
68 	for (int i = 0; i < CURSOR_BYTES; i += 16) {
69 		*fbCursor32++ = ~0;		// and bits
70 		*fbCursor32++ = ~0;
71 		*fbCursor32++ = 0;		// xor bits
72 		*fbCursor32++ = 0;
73 	}
74 
75 	// Now load the AND & XOR masks for the cursor image into the cursor
76 	// buffer.  Note that a particular bit in these masks will have the
77 	// following effect upon the corresponding cursor pixel:
78 	//	AND  XOR	Result
79 	//	 0    0		 White pixel
80 	//	 0    1		 Black pixel
81 	//	 1    0		 Screen color (for transparency)
82 	//	 1    1		 Reverse screen color to black or white
83 
84 	uint8* fbCursor = (uint8*)((addr_t)si.videoMemAddr + si.cursorOffset);
85 
86 	for (int row = 0; row < height; row++) {
87 		for (int colByte = 0; colByte < width / 8; colByte++) {
88 			fbCursor[row * 16 + colByte] = *andMask++;
89 			fbCursor[row * 16 + colByte + 8] = *xorMask++;
90 		}
91 	}
92 
93 	// Set the cursor colors which are white background and black foreground.
94 
95 	OUTREG(R128_CUR_CLR0, ~0);
96 	OUTREG(R128_CUR_CLR1, 0);
97 
98 	return true;
99 }
100