xref: /haiku/src/add-ons/accelerants/s3/virge_cursor.cpp (revision ed24eb5ff12640d052171c6a7feba37fab8a75d1)
1 /*
2 	Haiku S3 Virge driver adapted from the X.org Virge driver.
3 
4 	Copyright (C) 1994-1999 The XFree86 Project, Inc.	All Rights Reserved.
5 
6 	Copyright 2007-2008 Haiku, Inc.  All rights reserved.
7 	Distributed under the terms of the MIT license.
8 
9 	Authors:
10 	Gerald Zajac 2007-2008
11 */
12 
13 #include "accel.h"
14 #include "virge.h"
15 
16 
17 
18 void
19 Virge_ShowCursor(bool bShow)
20 {
21 	// Turn cursor on/off.
22 
23 	WriteCrtcReg(0x45, bShow ? 0x01 : 0x00, 0x01);
24 }
25 
26 
27 void
28 Virge_SetCursorPosition(int x, int y)
29 {
30 	uint8 xOffset = 0;
31 	uint8 yOffset = 0;
32 
33 	// xOffset & yOffset are used for displaying partial cursors on screen edges.
34 
35 	if (x < 0) {
36 		xOffset = (( -x) & 0xfe);
37 		x = 0;
38 	}
39 
40 	if (y < 0) {
41 		yOffset = (( -y) & 0xfe);
42 		y = 0;
43 	}
44 
45 	// Note: when setting the cursor position, register 48 must be set last
46 	// since setting register 48 activates the new cursor position.
47 
48 	WriteCrtcReg( 0x4e, xOffset );
49 	WriteCrtcReg( 0x4f, yOffset );
50 
51 	WriteCrtcReg( 0x47, (x & 0xff) );
52 	WriteCrtcReg( 0x46, (x & 0x0700) >> 8 );
53 
54 	WriteCrtcReg( 0x49, (y & 0xff) );
55 	WriteCrtcReg( 0x48, (y & 0x0700) >> 8 );
56 }
57 
58 
59 bool
60 Virge_LoadCursorImage(int width, int height, uint8* andMask, uint8* xorMask)
61 {
62 	SharedInfo& si = *gInfo.sharedInfo;
63 
64 	if (andMask == NULL || xorMask == NULL)
65 		return false;
66 
67 	// Initialize hardware cursor to be completely transparent.
68 
69 	uint16* fbCursor16 = (uint16*)((addr_t)si.videoMemAddr + si.cursorOffset);
70 
71 	for (int i = 0; i < CURSOR_BYTES; i += 4) {
72 		*fbCursor16++ = ~0;		// and bits
73 		*fbCursor16++ = 0;		// xor bits
74 	}
75 
76 	// Now load the AND & XOR masks for the cursor image into the cursor
77 	// buffer.  Note that a particular bit in these masks will have the
78 	// following effect upon the corresponding cursor pixel:
79 	//	AND  XOR	Result
80 	//	 0    0		 White pixel
81 	//	 0    1		 Black pixel
82 	//	 1    0		 Screen color (for transparency)
83 	//	 1    1		 Reverse screen color to black or white
84 
85 	uint8* fbCursor = (uint8*)((addr_t)si.videoMemAddr + si.cursorOffset);
86 
87 	for (int row = 0; row < height; row++) {
88 		for (int colByte = 0; colByte < width / 8; colByte++) {
89 			fbCursor[row * 16 + colByte] = *andMask++;
90 			fbCursor[row * 16 + colByte + 2] = *xorMask++;
91 		}
92 	}
93 
94 	// Set cursor location in video memory.
95 
96 	WriteCrtcReg(0x4d, (0xff & si.cursorOffset / 1024));
97 	WriteCrtcReg(0x4c, (0x0f00 & si.cursorOffset / 1024) >> 8);
98 
99 	// Set the cursor colors which are black foreground and white background.
100 
101 	ReadCrtcReg(0x45);		// reset cursor color stack pointer
102 	WriteCrtcReg(0x4a, 0);	// set foreground color stack low, mid, high bytes
103 	WriteCrtcReg(0x4a, 0);
104 	WriteCrtcReg(0x4a, 0);
105 
106 	ReadCrtcReg(0x45);		// reset cursor color stack pointer
107 	WriteCrtcReg(0x4b, ~0);	// set background color stack low, mid, high bytes
108 	WriteCrtcReg(0x4b, ~0);
109 	WriteCrtcReg(0x4b, ~0);
110 
111 	return true;
112 }
113