xref: /haiku/src/add-ons/accelerants/skeleton/Cursor.c (revision 6835336864a9a191c4de8a1b498a54ebb71264e6)
1*68353368SRudolf Cornelissen /*
2*68353368SRudolf Cornelissen 	Copyright 1999, Be Incorporated.   All Rights Reserved.
3*68353368SRudolf Cornelissen 	This file may be used under the terms of the Be Sample Code License.
4*68353368SRudolf Cornelissen 
5*68353368SRudolf Cornelissen 	Other authors:
6*68353368SRudolf Cornelissen 	Mark Watson,
7*68353368SRudolf Cornelissen 	Rudolf Cornelissen 4/2003-5/2004
8*68353368SRudolf Cornelissen */
9*68353368SRudolf Cornelissen 
10*68353368SRudolf Cornelissen #define MODULE_BIT 0x20000000
11*68353368SRudolf Cornelissen 
12*68353368SRudolf Cornelissen #include "acc_std.h"
13*68353368SRudolf Cornelissen 
14*68353368SRudolf Cornelissen status_t SET_CURSOR_SHAPE(uint16 width, uint16 height, uint16 hot_x, uint16 hot_y, uint8 *andMask, uint8 *xorMask)
15*68353368SRudolf Cornelissen {
16*68353368SRudolf Cornelissen 	LOG(4,("SET_CURSOR_SHAPE: width %d, height %d, hot_x %d, hot_y %d\n",
17*68353368SRudolf Cornelissen 		width, height, hot_x, hot_y));
18*68353368SRudolf Cornelissen 
19*68353368SRudolf Cornelissen 	if ((width != 16) || (height != 16))
20*68353368SRudolf Cornelissen 	{
21*68353368SRudolf Cornelissen 		return B_ERROR;
22*68353368SRudolf Cornelissen 	}
23*68353368SRudolf Cornelissen 	else if ((hot_x >= width) || (hot_y >= height))
24*68353368SRudolf Cornelissen 	{
25*68353368SRudolf Cornelissen 		return B_ERROR;
26*68353368SRudolf Cornelissen 	}
27*68353368SRudolf Cornelissen 	else
28*68353368SRudolf Cornelissen 	{
29*68353368SRudolf Cornelissen 		head1_cursor_define(andMask,xorMask);
30*68353368SRudolf Cornelissen 		if ((si->dm.flags & DUALHEAD_BITS) != DUALHEAD_OFF)
31*68353368SRudolf Cornelissen 			head2_cursor_define(andMask,xorMask);
32*68353368SRudolf Cornelissen 
33*68353368SRudolf Cornelissen 		/* Update cursor variables appropriately. */
34*68353368SRudolf Cornelissen 		si->cursor.width = width;
35*68353368SRudolf Cornelissen 		si->cursor.height = height;
36*68353368SRudolf Cornelissen 		si->cursor.hot_x = hot_x;
37*68353368SRudolf Cornelissen 		si->cursor.hot_y = hot_y;
38*68353368SRudolf Cornelissen 	}
39*68353368SRudolf Cornelissen 
40*68353368SRudolf Cornelissen 	return B_OK;
41*68353368SRudolf Cornelissen }
42*68353368SRudolf Cornelissen 
43*68353368SRudolf Cornelissen /* Move the cursor to the specified position on the desktop, taking account of virtual/dual issues */
44*68353368SRudolf Cornelissen void MOVE_CURSOR(uint16 x, uint16 y)
45*68353368SRudolf Cornelissen {
46*68353368SRudolf Cornelissen 	uint16 hds = si->dm.h_display_start;	/* the current horizontal starting pixel */
47*68353368SRudolf Cornelissen 	uint16 vds = si->dm.v_display_start;	/* the current vertical starting line */
48*68353368SRudolf Cornelissen 	uint16 h_adjust;
49*68353368SRudolf Cornelissen 
50*68353368SRudolf Cornelissen 	/* clamp cursor to display */
51*68353368SRudolf Cornelissen 	if (x >= si->dm.virtual_width) x = si->dm.virtual_width - 1;
52*68353368SRudolf Cornelissen 	if (y >= si->dm.virtual_height) y = si->dm.virtual_height - 1;
53*68353368SRudolf Cornelissen 
54*68353368SRudolf Cornelissen 	/* store, for our info */
55*68353368SRudolf Cornelissen 	si->cursor.x = x;
56*68353368SRudolf Cornelissen 	si->cursor.y = y;
57*68353368SRudolf Cornelissen 
58*68353368SRudolf Cornelissen 	/* setting up minimum amount to scroll not needed:
59*68353368SRudolf Cornelissen 	 * Nvidia cards can always do pixelprecise panning on both heads */
60*68353368SRudolf Cornelissen 	h_adjust = 0x00;
61*68353368SRudolf Cornelissen 
62*68353368SRudolf Cornelissen 	/* adjust h/v_display_start to move cursor onto screen */
63*68353368SRudolf Cornelissen 	switch (si->dm.flags & DUALHEAD_BITS)
64*68353368SRudolf Cornelissen 	{
65*68353368SRudolf Cornelissen 	case DUALHEAD_ON:
66*68353368SRudolf Cornelissen 	case DUALHEAD_SWITCH:
67*68353368SRudolf Cornelissen 		if (x >= ((si->dm.timing.h_display * 2) + hds))
68*68353368SRudolf Cornelissen 		{
69*68353368SRudolf Cornelissen 			hds = ((x - (si->dm.timing.h_display * 2)) + 1 + h_adjust) & ~h_adjust;
70*68353368SRudolf Cornelissen 			/* make sure we stay within the display! */
71*68353368SRudolf Cornelissen 			if ((hds + (si->dm.timing.h_display * 2)) > si->dm.virtual_width)
72*68353368SRudolf Cornelissen 				hds -= (h_adjust + 1);
73*68353368SRudolf Cornelissen 		}
74*68353368SRudolf Cornelissen 		else if (x < hds)
75*68353368SRudolf Cornelissen 			hds = x & ~h_adjust;
76*68353368SRudolf Cornelissen 		break;
77*68353368SRudolf Cornelissen 	default:
78*68353368SRudolf Cornelissen 		if (x >= (si->dm.timing.h_display + hds))
79*68353368SRudolf Cornelissen 		{
80*68353368SRudolf Cornelissen 			hds = ((x - si->dm.timing.h_display) + 1 + h_adjust) & ~h_adjust;
81*68353368SRudolf Cornelissen 			/* make sure we stay within the display! */
82*68353368SRudolf Cornelissen 			if ((hds + si->dm.timing.h_display) > si->dm.virtual_width)
83*68353368SRudolf Cornelissen 				hds -= (h_adjust + 1);
84*68353368SRudolf Cornelissen 		}
85*68353368SRudolf Cornelissen 		else if (x < hds)
86*68353368SRudolf Cornelissen 			hds = x & ~h_adjust;
87*68353368SRudolf Cornelissen 		break;
88*68353368SRudolf Cornelissen 	}
89*68353368SRudolf Cornelissen 
90*68353368SRudolf Cornelissen 	if (y >= (si->dm.timing.v_display + vds))
91*68353368SRudolf Cornelissen 		vds = y - si->dm.timing.v_display + 1;
92*68353368SRudolf Cornelissen 	else if (y < vds)
93*68353368SRudolf Cornelissen 		vds = y;
94*68353368SRudolf Cornelissen 
95*68353368SRudolf Cornelissen 	/* reposition the desktop _and_ the overlay on the display if required */
96*68353368SRudolf Cornelissen 	if ((hds!=si->dm.h_display_start) || (vds!=si->dm.v_display_start))
97*68353368SRudolf Cornelissen 	{
98*68353368SRudolf Cornelissen 		MOVE_DISPLAY(hds,vds);
99*68353368SRudolf Cornelissen 		nv_bes_move_overlay();
100*68353368SRudolf Cornelissen 	}
101*68353368SRudolf Cornelissen 
102*68353368SRudolf Cornelissen 	/* put cursor in correct physical position, so stay onscreen (rel. to CRTC) */
103*68353368SRudolf Cornelissen 	if (x > (hds + si->cursor.hot_x)) x -= (hds + si->cursor.hot_x);
104*68353368SRudolf Cornelissen 	else x = 0;
105*68353368SRudolf Cornelissen 	if (y > (vds + si->cursor.hot_y)) y -= (vds + si->cursor.hot_y);
106*68353368SRudolf Cornelissen 	else y = 0;
107*68353368SRudolf Cornelissen 
108*68353368SRudolf Cornelissen 	/* position the cursor on the display */
109*68353368SRudolf Cornelissen 	switch (si->dm.flags & DUALHEAD_BITS)
110*68353368SRudolf Cornelissen 	{
111*68353368SRudolf Cornelissen 	case DUALHEAD_CLONE:
112*68353368SRudolf Cornelissen 		head1_cursor_position(x,y);
113*68353368SRudolf Cornelissen 		head2_cursor_position(x,y);
114*68353368SRudolf Cornelissen 		break;
115*68353368SRudolf Cornelissen 	case DUALHEAD_ON:
116*68353368SRudolf Cornelissen 	case DUALHEAD_SWITCH:
117*68353368SRudolf Cornelissen 		if (x < si->dm.timing.h_display)
118*68353368SRudolf Cornelissen 		{
119*68353368SRudolf Cornelissen 			if (si->cursor.dh_right)
120*68353368SRudolf Cornelissen 			{
121*68353368SRudolf Cornelissen 				LOG(4,("MOVE_CURSOR: now on left side\n"));
122*68353368SRudolf Cornelissen 				head2_cursor_hide();
123*68353368SRudolf Cornelissen 				head1_cursor_show();
124*68353368SRudolf Cornelissen 				si->cursor.dh_right = false;
125*68353368SRudolf Cornelissen 			}
126*68353368SRudolf Cornelissen 			head1_cursor_position(x, y);
127*68353368SRudolf Cornelissen 		}
128*68353368SRudolf Cornelissen 		else
129*68353368SRudolf Cornelissen 		{
130*68353368SRudolf Cornelissen 			if (!si->cursor.dh_right)
131*68353368SRudolf Cornelissen 			{
132*68353368SRudolf Cornelissen 				LOG(4,("MOVE_CURSOR: now on right side\n"));
133*68353368SRudolf Cornelissen 				head1_cursor_hide();
134*68353368SRudolf Cornelissen 				head2_cursor_show();
135*68353368SRudolf Cornelissen 				si->cursor.dh_right = true;
136*68353368SRudolf Cornelissen 			}
137*68353368SRudolf Cornelissen 			head2_cursor_position((x - si->dm.timing.h_display), y);
138*68353368SRudolf Cornelissen 		}
139*68353368SRudolf Cornelissen 		break;
140*68353368SRudolf Cornelissen 	default: /* singlehead mode */
141*68353368SRudolf Cornelissen 		head1_cursor_position(x,y);
142*68353368SRudolf Cornelissen 		break;
143*68353368SRudolf Cornelissen 	}
144*68353368SRudolf Cornelissen }
145*68353368SRudolf Cornelissen 
146*68353368SRudolf Cornelissen void SHOW_CURSOR(bool is_visible)
147*68353368SRudolf Cornelissen {
148*68353368SRudolf Cornelissen 	/* record for our info */
149*68353368SRudolf Cornelissen 	si->cursor.is_visible = is_visible;
150*68353368SRudolf Cornelissen 
151*68353368SRudolf Cornelissen 	switch (si->dm.flags & DUALHEAD_BITS)
152*68353368SRudolf Cornelissen 	{
153*68353368SRudolf Cornelissen 	case DUALHEAD_CLONE:
154*68353368SRudolf Cornelissen 		if (is_visible)
155*68353368SRudolf Cornelissen 		{
156*68353368SRudolf Cornelissen 			head1_cursor_show();
157*68353368SRudolf Cornelissen 			head2_cursor_show();
158*68353368SRudolf Cornelissen 		}
159*68353368SRudolf Cornelissen 		else
160*68353368SRudolf Cornelissen 		{
161*68353368SRudolf Cornelissen 			head1_cursor_hide();
162*68353368SRudolf Cornelissen 			head2_cursor_hide();
163*68353368SRudolf Cornelissen 		}
164*68353368SRudolf Cornelissen 		break;
165*68353368SRudolf Cornelissen 	case DUALHEAD_ON:
166*68353368SRudolf Cornelissen 	case DUALHEAD_SWITCH:
167*68353368SRudolf Cornelissen 		if (is_visible)
168*68353368SRudolf Cornelissen 		{
169*68353368SRudolf Cornelissen 			if (!si->cursor.dh_right)
170*68353368SRudolf Cornelissen 			{
171*68353368SRudolf Cornelissen 				head1_cursor_show();
172*68353368SRudolf Cornelissen 			}
173*68353368SRudolf Cornelissen 			else
174*68353368SRudolf Cornelissen 			{
175*68353368SRudolf Cornelissen 				head2_cursor_show();
176*68353368SRudolf Cornelissen 			}
177*68353368SRudolf Cornelissen 		}
178*68353368SRudolf Cornelissen 		else
179*68353368SRudolf Cornelissen 		{
180*68353368SRudolf Cornelissen 			head1_cursor_hide();
181*68353368SRudolf Cornelissen 			head2_cursor_hide();
182*68353368SRudolf Cornelissen 		}
183*68353368SRudolf Cornelissen 		break;
184*68353368SRudolf Cornelissen 	default: /* singlehead mode */
185*68353368SRudolf Cornelissen 		if (is_visible)
186*68353368SRudolf Cornelissen 		{
187*68353368SRudolf Cornelissen 			head1_cursor_show();
188*68353368SRudolf Cornelissen 		}
189*68353368SRudolf Cornelissen 		else
190*68353368SRudolf Cornelissen 		{
191*68353368SRudolf Cornelissen 			head1_cursor_hide();
192*68353368SRudolf Cornelissen 		}
193*68353368SRudolf Cornelissen 		break;
194*68353368SRudolf Cornelissen 	}
195*68353368SRudolf Cornelissen }
196