xref: /haiku/src/add-ons/accelerants/skeleton/Cursor.c (revision 886dbf812e484824d4ea185989639457b18e28f2)
168353368SRudolf Cornelissen /*
268353368SRudolf Cornelissen 	Copyright 1999, Be Incorporated.   All Rights Reserved.
368353368SRudolf Cornelissen 	This file may be used under the terms of the Be Sample Code License.
468353368SRudolf Cornelissen 
568353368SRudolf Cornelissen 	Other authors:
668353368SRudolf Cornelissen 	Mark Watson,
768353368SRudolf Cornelissen 	Rudolf Cornelissen 4/2003-5/2004
868353368SRudolf Cornelissen */
968353368SRudolf Cornelissen 
1068353368SRudolf Cornelissen #define MODULE_BIT 0x20000000
1168353368SRudolf Cornelissen 
1268353368SRudolf Cornelissen #include "acc_std.h"
1368353368SRudolf Cornelissen 
SET_CURSOR_SHAPE(uint16 width,uint16 height,uint16 hot_x,uint16 hot_y,uint8 * andMask,uint8 * xorMask)1468353368SRudolf Cornelissen status_t SET_CURSOR_SHAPE(uint16 width, uint16 height, uint16 hot_x, uint16 hot_y, uint8 *andMask, uint8 *xorMask)
1568353368SRudolf Cornelissen {
1668353368SRudolf Cornelissen 	LOG(4,("SET_CURSOR_SHAPE: width %d, height %d, hot_x %d, hot_y %d\n",
1768353368SRudolf Cornelissen 		width, height, hot_x, hot_y));
1868353368SRudolf Cornelissen 
1968353368SRudolf Cornelissen 	if ((width != 16) || (height != 16))
2068353368SRudolf Cornelissen 	{
2168353368SRudolf Cornelissen 		return B_ERROR;
2268353368SRudolf Cornelissen 	}
2368353368SRudolf Cornelissen 	else if ((hot_x >= width) || (hot_y >= height))
2468353368SRudolf Cornelissen 	{
2568353368SRudolf Cornelissen 		return B_ERROR;
2668353368SRudolf Cornelissen 	}
2768353368SRudolf Cornelissen 	else
2868353368SRudolf Cornelissen 	{
2968353368SRudolf Cornelissen 		head1_cursor_define(andMask,xorMask);
3068353368SRudolf Cornelissen 		if ((si->dm.flags & DUALHEAD_BITS) != DUALHEAD_OFF)
3168353368SRudolf Cornelissen 			head2_cursor_define(andMask,xorMask);
3268353368SRudolf Cornelissen 
3368353368SRudolf Cornelissen 		/* Update cursor variables appropriately. */
3468353368SRudolf Cornelissen 		si->cursor.width = width;
3568353368SRudolf Cornelissen 		si->cursor.height = height;
3668353368SRudolf Cornelissen 		si->cursor.hot_x = hot_x;
3768353368SRudolf Cornelissen 		si->cursor.hot_y = hot_y;
3868353368SRudolf Cornelissen 	}
3968353368SRudolf Cornelissen 
4068353368SRudolf Cornelissen 	return B_OK;
4168353368SRudolf Cornelissen }
4268353368SRudolf Cornelissen 
4368353368SRudolf Cornelissen /* Move the cursor to the specified position on the desktop, taking account of virtual/dual issues */
MOVE_CURSOR(uint16 x,uint16 y)4468353368SRudolf Cornelissen void MOVE_CURSOR(uint16 x, uint16 y)
4568353368SRudolf Cornelissen {
4668353368SRudolf Cornelissen 	uint16 hds = si->dm.h_display_start;	/* the current horizontal starting pixel */
4768353368SRudolf Cornelissen 	uint16 vds = si->dm.v_display_start;	/* the current vertical starting line */
4868353368SRudolf Cornelissen 	uint16 h_adjust;
4968353368SRudolf Cornelissen 
5068353368SRudolf Cornelissen 	/* clamp cursor to display */
5168353368SRudolf Cornelissen 	if (x >= si->dm.virtual_width) x = si->dm.virtual_width - 1;
5268353368SRudolf Cornelissen 	if (y >= si->dm.virtual_height) y = si->dm.virtual_height - 1;
5368353368SRudolf Cornelissen 
5468353368SRudolf Cornelissen 	/* store, for our info */
5568353368SRudolf Cornelissen 	si->cursor.x = x;
5668353368SRudolf Cornelissen 	si->cursor.y = y;
5768353368SRudolf Cornelissen 
5868353368SRudolf Cornelissen 	/* setting up minimum amount to scroll not needed:
5968353368SRudolf Cornelissen 	 * Nvidia cards can always do pixelprecise panning on both heads */
6068353368SRudolf Cornelissen 	h_adjust = 0x00;
6168353368SRudolf Cornelissen 
6268353368SRudolf Cornelissen 	/* adjust h/v_display_start to move cursor onto screen */
6368353368SRudolf Cornelissen 	switch (si->dm.flags & DUALHEAD_BITS)
6468353368SRudolf Cornelissen 	{
6568353368SRudolf Cornelissen 	case DUALHEAD_ON:
6668353368SRudolf Cornelissen 	case DUALHEAD_SWITCH:
6768353368SRudolf Cornelissen 		if (x >= ((si->dm.timing.h_display * 2) + hds))
6868353368SRudolf Cornelissen 		{
6968353368SRudolf Cornelissen 			hds = ((x - (si->dm.timing.h_display * 2)) + 1 + h_adjust) & ~h_adjust;
7068353368SRudolf Cornelissen 			/* make sure we stay within the display! */
7168353368SRudolf Cornelissen 			if ((hds + (si->dm.timing.h_display * 2)) > si->dm.virtual_width)
7268353368SRudolf Cornelissen 				hds -= (h_adjust + 1);
7368353368SRudolf Cornelissen 		}
7468353368SRudolf Cornelissen 		else if (x < hds)
7568353368SRudolf Cornelissen 			hds = x & ~h_adjust;
7668353368SRudolf Cornelissen 		break;
7768353368SRudolf Cornelissen 	default:
7868353368SRudolf Cornelissen 		if (x >= (si->dm.timing.h_display + hds))
7968353368SRudolf Cornelissen 		{
8068353368SRudolf Cornelissen 			hds = ((x - si->dm.timing.h_display) + 1 + h_adjust) & ~h_adjust;
8168353368SRudolf Cornelissen 			/* make sure we stay within the display! */
8268353368SRudolf Cornelissen 			if ((hds + si->dm.timing.h_display) > si->dm.virtual_width)
8368353368SRudolf Cornelissen 				hds -= (h_adjust + 1);
8468353368SRudolf Cornelissen 		}
8568353368SRudolf Cornelissen 		else if (x < hds)
8668353368SRudolf Cornelissen 			hds = x & ~h_adjust;
8768353368SRudolf Cornelissen 		break;
8868353368SRudolf Cornelissen 	}
8968353368SRudolf Cornelissen 
9068353368SRudolf Cornelissen 	if (y >= (si->dm.timing.v_display + vds))
9168353368SRudolf Cornelissen 		vds = y - si->dm.timing.v_display + 1;
9268353368SRudolf Cornelissen 	else if (y < vds)
9368353368SRudolf Cornelissen 		vds = y;
9468353368SRudolf Cornelissen 
9568353368SRudolf Cornelissen 	/* reposition the desktop _and_ the overlay on the display if required */
9668353368SRudolf Cornelissen 	if ((hds!=si->dm.h_display_start) || (vds!=si->dm.v_display_start))
9768353368SRudolf Cornelissen 	{
9868353368SRudolf Cornelissen 		MOVE_DISPLAY(hds,vds);
99*886dbf81SRudolf Cornelissen 		eng_bes_move_overlay();
10068353368SRudolf Cornelissen 	}
10168353368SRudolf Cornelissen 
10268353368SRudolf Cornelissen 	/* put cursor in correct physical position, so stay onscreen (rel. to CRTC) */
10368353368SRudolf Cornelissen 	if (x > (hds + si->cursor.hot_x)) x -= (hds + si->cursor.hot_x);
10468353368SRudolf Cornelissen 	else x = 0;
10568353368SRudolf Cornelissen 	if (y > (vds + si->cursor.hot_y)) y -= (vds + si->cursor.hot_y);
10668353368SRudolf Cornelissen 	else y = 0;
10768353368SRudolf Cornelissen 
10868353368SRudolf Cornelissen 	/* position the cursor on the display */
10968353368SRudolf Cornelissen 	switch (si->dm.flags & DUALHEAD_BITS)
11068353368SRudolf Cornelissen 	{
11168353368SRudolf Cornelissen 	case DUALHEAD_CLONE:
11268353368SRudolf Cornelissen 		head1_cursor_position(x,y);
11368353368SRudolf Cornelissen 		head2_cursor_position(x,y);
11468353368SRudolf Cornelissen 		break;
11568353368SRudolf Cornelissen 	case DUALHEAD_ON:
11668353368SRudolf Cornelissen 	case DUALHEAD_SWITCH:
11768353368SRudolf Cornelissen 		if (x < si->dm.timing.h_display)
11868353368SRudolf Cornelissen 		{
11968353368SRudolf Cornelissen 			if (si->cursor.dh_right)
12068353368SRudolf Cornelissen 			{
12168353368SRudolf Cornelissen 				LOG(4,("MOVE_CURSOR: now on left side\n"));
12268353368SRudolf Cornelissen 				head2_cursor_hide();
12368353368SRudolf Cornelissen 				head1_cursor_show();
12468353368SRudolf Cornelissen 				si->cursor.dh_right = false;
12568353368SRudolf Cornelissen 			}
12668353368SRudolf Cornelissen 			head1_cursor_position(x, y);
12768353368SRudolf Cornelissen 		}
12868353368SRudolf Cornelissen 		else
12968353368SRudolf Cornelissen 		{
13068353368SRudolf Cornelissen 			if (!si->cursor.dh_right)
13168353368SRudolf Cornelissen 			{
13268353368SRudolf Cornelissen 				LOG(4,("MOVE_CURSOR: now on right side\n"));
13368353368SRudolf Cornelissen 				head1_cursor_hide();
13468353368SRudolf Cornelissen 				head2_cursor_show();
13568353368SRudolf Cornelissen 				si->cursor.dh_right = true;
13668353368SRudolf Cornelissen 			}
13768353368SRudolf Cornelissen 			head2_cursor_position((x - si->dm.timing.h_display), y);
13868353368SRudolf Cornelissen 		}
13968353368SRudolf Cornelissen 		break;
14068353368SRudolf Cornelissen 	default: /* singlehead mode */
14168353368SRudolf Cornelissen 		head1_cursor_position(x,y);
14268353368SRudolf Cornelissen 		break;
14368353368SRudolf Cornelissen 	}
14468353368SRudolf Cornelissen }
14568353368SRudolf Cornelissen 
SHOW_CURSOR(bool is_visible)14668353368SRudolf Cornelissen void SHOW_CURSOR(bool is_visible)
14768353368SRudolf Cornelissen {
14868353368SRudolf Cornelissen 	/* record for our info */
14968353368SRudolf Cornelissen 	si->cursor.is_visible = is_visible;
15068353368SRudolf Cornelissen 
15168353368SRudolf Cornelissen 	switch (si->dm.flags & DUALHEAD_BITS)
15268353368SRudolf Cornelissen 	{
15368353368SRudolf Cornelissen 	case DUALHEAD_CLONE:
15468353368SRudolf Cornelissen 		if (is_visible)
15568353368SRudolf Cornelissen 		{
15668353368SRudolf Cornelissen 			head1_cursor_show();
15768353368SRudolf Cornelissen 			head2_cursor_show();
15868353368SRudolf Cornelissen 		}
15968353368SRudolf Cornelissen 		else
16068353368SRudolf Cornelissen 		{
16168353368SRudolf Cornelissen 			head1_cursor_hide();
16268353368SRudolf Cornelissen 			head2_cursor_hide();
16368353368SRudolf Cornelissen 		}
16468353368SRudolf Cornelissen 		break;
16568353368SRudolf Cornelissen 	case DUALHEAD_ON:
16668353368SRudolf Cornelissen 	case DUALHEAD_SWITCH:
16768353368SRudolf Cornelissen 		if (is_visible)
16868353368SRudolf Cornelissen 		{
16968353368SRudolf Cornelissen 			if (!si->cursor.dh_right)
17068353368SRudolf Cornelissen 			{
17168353368SRudolf Cornelissen 				head1_cursor_show();
17268353368SRudolf Cornelissen 			}
17368353368SRudolf Cornelissen 			else
17468353368SRudolf Cornelissen 			{
17568353368SRudolf Cornelissen 				head2_cursor_show();
17668353368SRudolf Cornelissen 			}
17768353368SRudolf Cornelissen 		}
17868353368SRudolf Cornelissen 		else
17968353368SRudolf Cornelissen 		{
18068353368SRudolf Cornelissen 			head1_cursor_hide();
18168353368SRudolf Cornelissen 			head2_cursor_hide();
18268353368SRudolf Cornelissen 		}
18368353368SRudolf Cornelissen 		break;
18468353368SRudolf Cornelissen 	default: /* singlehead mode */
18568353368SRudolf Cornelissen 		if (is_visible)
18668353368SRudolf Cornelissen 		{
18768353368SRudolf Cornelissen 			head1_cursor_show();
18868353368SRudolf Cornelissen 		}
18968353368SRudolf Cornelissen 		else
19068353368SRudolf Cornelissen 		{
19168353368SRudolf Cornelissen 			head1_cursor_hide();
19268353368SRudolf Cornelissen 		}
19368353368SRudolf Cornelissen 		break;
19468353368SRudolf Cornelissen 	}
19568353368SRudolf Cornelissen }
196