xref: /haiku/src/add-ons/accelerants/intel_extreme/cursor.cpp (revision 1c34b9b1f5e168501f89a270233457e04aa1b16b)
17d5957dfSAxel Dörfler /*
2*1c34b9b1SAxel Dörfler  * Copyright 2006-2008, Haiku, Inc. All Rights Reserved.
37d5957dfSAxel Dörfler  * Distributed under the terms of the MIT License.
47d5957dfSAxel Dörfler  *
57d5957dfSAxel Dörfler  * Authors:
67d5957dfSAxel Dörfler  *		Axel Dörfler, axeld@pinc-software.de
77d5957dfSAxel Dörfler  */
87d5957dfSAxel Dörfler 
97d5957dfSAxel Dörfler 
107d5957dfSAxel Dörfler #include "accelerant_protos.h"
117d5957dfSAxel Dörfler #include "accelerant.h"
127d5957dfSAxel Dörfler 
137d5957dfSAxel Dörfler #include <string.h>
147d5957dfSAxel Dörfler 
157d5957dfSAxel Dörfler 
167d5957dfSAxel Dörfler status_t
177d5957dfSAxel Dörfler intel_set_cursor_shape(uint16 width, uint16 height, uint16 hotX, uint16 hotY,
187d5957dfSAxel Dörfler 	uint8 *andMask, uint8 *xorMask)
197d5957dfSAxel Dörfler {
207d5957dfSAxel Dörfler 	if (width > 64 || height > 64)
217d5957dfSAxel Dörfler 		return B_BAD_VALUE;
227d5957dfSAxel Dörfler 
237d5957dfSAxel Dörfler 	write32(INTEL_CURSOR_CONTROL, 0);
247d5957dfSAxel Dörfler 		// disable cursor
257d5957dfSAxel Dörfler 
267d5957dfSAxel Dörfler 	// In two-color mode, the data is ordered as follows (always 64 bit per line):
277d5957dfSAxel Dörfler 	//	plane 1: line 0 (AND mask)
287d5957dfSAxel Dörfler 	//	plane 0: line 0 (XOR mask)
297d5957dfSAxel Dörfler 	//	plane 1: line 1 (AND mask)
307d5957dfSAxel Dörfler 	//	...
317d5957dfSAxel Dörfler 	//
327d5957dfSAxel Dörfler 	// If the planes add to the value 0x2, the corresponding pixel is
337d5957dfSAxel Dörfler 	// transparent, for 0x3 it inverts the background, so only the first
347d5957dfSAxel Dörfler 	// two palette entries will be used (since we're using the 2 color mode).
357d5957dfSAxel Dörfler 
36*1c34b9b1SAxel Dörfler 	uint8 *data = gInfo->shared_info->cursor_memory;
377d5957dfSAxel Dörfler 	uint8 byteWidth = (width + 7) / 8;
387d5957dfSAxel Dörfler 
397d5957dfSAxel Dörfler 	for (int32 y = 0; y < height; y++) {
407d5957dfSAxel Dörfler 		for (int32 x = 0; x < byteWidth; x++) {
417d5957dfSAxel Dörfler 			data[16 * y + x] = andMask[byteWidth * y + x];
427d5957dfSAxel Dörfler 			data[16 * y + x + 8] = xorMask[byteWidth * y + x];
437d5957dfSAxel Dörfler 		}
447d5957dfSAxel Dörfler 	}
457d5957dfSAxel Dörfler 
467d5957dfSAxel Dörfler 	// We can only change the width of the pixel, but apparently
477d5957dfSAxel Dörfler 	// not the height (or at least I couldn't figure out how),
487d5957dfSAxel Dörfler 	// so we need to make the rest transparent
497d5957dfSAxel Dörfler 	for (uint32 y = height; y < 64; y++) {
507d5957dfSAxel Dörfler 		for (int32 x = 0; x < byteWidth; x++) {
517d5957dfSAxel Dörfler 			data[16 * y + x] = 0xff;
527d5957dfSAxel Dörfler 			data[16 * y + x + 8] = 0;
537d5957dfSAxel Dörfler 		}
547d5957dfSAxel Dörfler 	}
557d5957dfSAxel Dörfler 
567d5957dfSAxel Dörfler 	// set palette entries to white/black
577d5957dfSAxel Dörfler 	write32(INTEL_CURSOR_PALETTE + 0, 0x00ffffff);
587d5957dfSAxel Dörfler 	write32(INTEL_CURSOR_PALETTE + 4, 0);
597d5957dfSAxel Dörfler 
607d5957dfSAxel Dörfler 	gInfo->shared_info->cursor_format = CURSOR_FORMAT_2_COLORS;
617d5957dfSAxel Dörfler 
627d5957dfSAxel Dörfler 	write32(INTEL_CURSOR_CONTROL, CURSOR_ENABLED | gInfo->shared_info->cursor_format);
637d5957dfSAxel Dörfler 	write32(INTEL_CURSOR_SIZE, width);
647d5957dfSAxel Dörfler 		// TODO: I've no idea how to specify the height of the cursor - it seems to
657d5957dfSAxel Dörfler 		//	be always 64 pixels
667d5957dfSAxel Dörfler 
677d5957dfSAxel Dörfler 	write32(INTEL_CURSOR_BASE, (uint32)gInfo->shared_info->physical_graphics_memory
687d5957dfSAxel Dörfler 		+ gInfo->shared_info->cursor_buffer_offset);
697d5957dfSAxel Dörfler 
707d5957dfSAxel Dörfler 	// changing the hot point changes the cursor position, too
717d5957dfSAxel Dörfler 
727d5957dfSAxel Dörfler 	if (hotX != gInfo->shared_info->cursor_hot_x
737d5957dfSAxel Dörfler 		|| hotY != gInfo->shared_info->cursor_hot_y) {
747d5957dfSAxel Dörfler 		int32 x = read32(INTEL_CURSOR_POSITION);
757d5957dfSAxel Dörfler 		int32 y = x >> 16;
767d5957dfSAxel Dörfler 		x &= 0xffff;
777d5957dfSAxel Dörfler 
787d5957dfSAxel Dörfler 		if (x & CURSOR_POSITION_NEGATIVE)
797d5957dfSAxel Dörfler 			x = -(x & CURSOR_POSITION_MASK);
807d5957dfSAxel Dörfler 		if (y & CURSOR_POSITION_NEGATIVE)
817d5957dfSAxel Dörfler 			y = -(y & CURSOR_POSITION_MASK);
827d5957dfSAxel Dörfler 
837d5957dfSAxel Dörfler 		x += gInfo->shared_info->cursor_hot_x;
847d5957dfSAxel Dörfler 		y += gInfo->shared_info->cursor_hot_y;
857d5957dfSAxel Dörfler 
867d5957dfSAxel Dörfler 		gInfo->shared_info->cursor_hot_x = hotX;
877d5957dfSAxel Dörfler 		gInfo->shared_info->cursor_hot_y = hotY;
887d5957dfSAxel Dörfler 
897d5957dfSAxel Dörfler 		intel_move_cursor(x, y);
907d5957dfSAxel Dörfler 	}
917d5957dfSAxel Dörfler 
927d5957dfSAxel Dörfler 	return B_OK;
937d5957dfSAxel Dörfler }
947d5957dfSAxel Dörfler 
957d5957dfSAxel Dörfler 
967d5957dfSAxel Dörfler void
977d5957dfSAxel Dörfler intel_move_cursor(uint16 _x, uint16 _y)
987d5957dfSAxel Dörfler {
997d5957dfSAxel Dörfler 	int32 x = (int32)_x - gInfo->shared_info->cursor_hot_x;
1007d5957dfSAxel Dörfler 	int32 y = (int32)_y - gInfo->shared_info->cursor_hot_x;
1017d5957dfSAxel Dörfler 
1027d5957dfSAxel Dörfler 	if (x < 0)
1037d5957dfSAxel Dörfler 		x = -x | CURSOR_POSITION_NEGATIVE;
1047d5957dfSAxel Dörfler 	if (y < 0)
1057d5957dfSAxel Dörfler 		y = -y | CURSOR_POSITION_NEGATIVE;
1067d5957dfSAxel Dörfler 
1077d5957dfSAxel Dörfler 	write32(INTEL_CURSOR_POSITION, (y << 16) | x);
1087d5957dfSAxel Dörfler }
1097d5957dfSAxel Dörfler 
1107d5957dfSAxel Dörfler 
1117d5957dfSAxel Dörfler void
1127d5957dfSAxel Dörfler intel_show_cursor(bool isVisible)
1137d5957dfSAxel Dörfler {
1147d5957dfSAxel Dörfler 	if (gInfo->shared_info->cursor_visible == isVisible)
1157d5957dfSAxel Dörfler 		return;
1167d5957dfSAxel Dörfler 
1177d5957dfSAxel Dörfler 	write32(INTEL_CURSOR_CONTROL, (isVisible ? CURSOR_ENABLED : 0)
1187d5957dfSAxel Dörfler 		| gInfo->shared_info->cursor_format);
1197d5957dfSAxel Dörfler 	write32(INTEL_CURSOR_BASE, (uint32)gInfo->shared_info->physical_graphics_memory
1207d5957dfSAxel Dörfler 		+ gInfo->shared_info->cursor_buffer_offset);
1217d5957dfSAxel Dörfler 
1227d5957dfSAxel Dörfler 	gInfo->shared_info->cursor_visible = isVisible;
1237d5957dfSAxel Dörfler }
1247d5957dfSAxel Dörfler 
125