1/*
2 * Copyright 1999, Be Incorporated.
3 * Copyright 2007, Haiku.
4 * Distributed under the terms of the MIT License.
5 *
6 * Authors:
7 *		Be Incorporated
8 *		Eric Petit <eric.petit@lapsus.org>
9 *		Michael Pfeiffer <laplace@users.sourceforge.net>
10 */
11
12
13#include <string.h>
14#include "GlobalData.h"
15
16
17static void
18WriteScanline(void * scanline, uint16 sizeInBytes)
19{
20	uint32* words = (uint32*)scanline;
21	/* sizeInBytes must be a multiple of 4 */
22	uint16 sizeInWords = sizeInBytes / 4;
23	uint16 i;
24	for (i = 0; i < sizeInWords; i ++)
25		FifoWrite(words[i]);
26}
27
28
29static void
30WriteAndMask(uint8 * andMask, uint16 width, uint16 height, uint8 * scanline,
31		uint16 scanlineSize)
32{
33	uint16 y;
34	uint16 bpr = (width + 7) / 8;
35	for (y = 0; y < height; y ++) {
36		// copy andMask into scanline to avoid
37		// out of bounds access at last row
38		memcpy(scanline, &andMask[y * bpr], bpr);
39		WriteScanline(scanline, scanlineSize);
40	}
41}
42
43
44static void
45WriteXorMask(uint8 * andMask, uint8 * xorMask, uint16 width, uint16 height,
46		uint8 * scanline, uint16 scanlineSize)
47{
48	uint16 x;
49	uint16 y;
50	uint16 bpr = (width + 7) / 8;
51	for (y = 0; y < height; y ++) {
52		uint8 * andMaskRow = &andMask[y * bpr];
53		// copy xorMask into scanline to avoid
54		// out of bounds access at last row
55		memcpy(scanline,  &xorMask[y * bpr], bpr);
56		// in case of a 1 bit in andMask
57		// the meaning of the corresponding bit
58		// in xorMask is the opposite in the
59		// emulated graphics HW (1 = white, 0 =
60		// black). Be API: 1 = black, 0 = white.
61		for (x = 0; x < width; x ++) {
62			uint8 bit = 7 - x % 8;
63			uint8 bitMask = 1 << bit;
64			uint16 byte = x / 8;
65			if ((andMaskRow[byte] & bitMask) == 0)
66				scanline[byte] = scanline[byte] ^ bitMask;
67		}
68		WriteScanline(scanline, scanlineSize);
69	}
70}
71
72
73status_t
74SET_CURSOR_SHAPE(uint16 width, uint16 height, uint16 hot_x,
75	uint16 hot_y, uint8 * andMask, uint8 * xorMask)
76{
77
78	uint16 scanlineSize;
79	uint8 * scanline;
80
81	TRACE("SET_CURSOR_SHAPE (%d, %d, %d, %d)\n", width, height, hot_x, hot_y);
82
83	/* Sanity check */
84	if (hot_x >= width || hot_y >= height)
85		return B_ERROR;
86
87	scanlineSize = 4 * ((width + 31) / 32);
88	scanline = calloc(1, scanlineSize);
89	if (scanline == NULL)
90		return B_ERROR;
91
92	FifoBeginWrite();
93	FifoWrite(SVGA_CMD_DEFINE_CURSOR);
94	FifoWrite(CURSOR_ID);
95	FifoWrite(hot_x);
96	FifoWrite(hot_y);
97	FifoWrite(width);
98	FifoWrite(height);
99	FifoWrite(1);
100	FifoWrite(1);
101	WriteAndMask(andMask, width, height, scanline, scanlineSize);
102	WriteXorMask(andMask, xorMask, width, height, scanline, scanlineSize);
103	FifoEndWrite();
104	FifoSync();
105
106	free(scanline);
107
108	return B_OK;
109}
110
111
112void
113MOVE_CURSOR(uint16 x, uint16 y)
114{
115	uint16 pos[2];
116
117	//TRACE("MOVE_CURSOR (%d, %d)\n", x, y);
118
119	pos[0] = x;
120	pos[1] = y;
121	ioctl(gFd, VMWARE_MOVE_CURSOR, pos, sizeof(pos));
122}
123
124
125void
126SHOW_CURSOR(bool isVisible)
127{
128	TRACE("SHOW_CURSOR (%d)\n", isVisible);
129
130	ioctl(gFd, VMWARE_SHOW_CURSOR, &isVisible, sizeof(bool));
131}
132
133