xref: /haiku/src/add-ons/accelerants/matrox/Cursor.c (revision 091b52d5b26b0fb530a4bca8318832c2afe7d3bf)
1 /*
2 	Copyright 1999, Be Incorporated.   All Rights Reserved.
3 	This file may be used under the terms of the Be Sample Code License.
4 
5 	Other authors:
6 	Mark Watson
7 */
8 
9 #define MODULE_BIT 0x20000000
10 
11 /*DUALHEAD notes -
12 	No hardware cursor possible:(
13 		Reasons:
14 		CRTC1 has a cursor, can be displayed on DAC or MAVEN
15 		CRTC2 has no cursor
16 		Can not switch CRTC in one vblank (has to resync)
17 		CRTC2 does not support split screen
18 		app_server does not support some modes with and some without cursor
19 	virtual not supported, because of MAVEN blanking issues
20 */
21 
22 #include "acc_std.h"
23 
24 status_t SET_CURSOR_SHAPE(uint16 width, uint16 height, uint16 hot_x, uint16 hot_y, uint8 *andMask, uint8 *xorMask)
25 {
26 	LOG(4,("SET_CURSOR_SHAPE: width %d, height %d\n", width, height));
27 	if ((width != 16) || (height != 16))
28 	{
29 		return B_ERROR;
30 	}
31 	else if ((hot_x >= width) || (hot_y >= height))
32 	{
33 		return B_ERROR;
34 	}
35 	else
36 	{
37 		gx00_crtc_cursor_define(andMask,xorMask);
38 
39 		/* Update cursor variables appropriately. */
40 		si->cursor.width = width;
41 		si->cursor.height = height;
42 		si->cursor.hot_x = hot_x;
43 		si->cursor.hot_y = hot_y;
44 	}
45 
46 	return B_OK;
47 }
48 
49 /* Move the cursor to the specified position on the desktop, taking account of virtual/dual issues */
50 void MOVE_CURSOR(uint16 x, uint16 y)
51 {
52 	uint16 hds = si->dm.h_display_start;	/* the current horizontal starting pixel */
53 	uint16 vds = si->dm.v_display_start;	/* the current vertical starting line */
54 	uint16 h_adjust;
55 
56 	/* clamp cursor to display */
57 	if (x >= si->dm.virtual_width) x = si->dm.virtual_width-1;
58 	if (y >= si->dm.virtual_height) y = si->dm.virtual_height-1;
59 
60 	/* store, for our info */
61 	si->cursor.x=x;
62 	si->cursor.y=y;
63 
64 	/*set up minimum amount to scroll*/
65 	switch(si->dm.space)
66 	{
67 	case B_CMAP8:
68 		h_adjust=7;
69 		break;
70 	case B_RGB15_LITTLE:case B_RGB16_LITTLE:
71 		h_adjust=3;
72 		break;
73 	case B_RGB32_LITTLE:
74 		h_adjust=1;
75 		break;
76 	default:
77 		h_adjust=7;
78 	}
79 
80 	/* adjust h/v_display_start to move cursor onto screen */
81 	if (x >= (si->dm.timing.h_display + hds))
82 		hds = ((x - si->dm.timing.h_display) + 1 + h_adjust) & ~h_adjust;
83 	else if (x < hds)
84 		hds = x & ~h_adjust;
85 
86 	if (y >= (si->dm.timing.v_display + vds))
87 		vds = y - si->dm.timing.v_display + 1;
88 	else if (y < vds)
89 		vds = y;
90 
91 	/* reposition the desktop on the display if required */
92 	if ((hds!=si->dm.h_display_start) || (vds!=si->dm.v_display_start))
93 		MOVE_DISPLAY(hds,vds);
94 
95 	/* put cursor in correct physical position */
96 	x -= hds + si->cursor.hot_x;
97 	y -= vds + si->cursor.hot_y;
98 
99 	/* position the cursor on the display */
100 	gx00_crtc_cursor_position(x,y);
101 }
102 
103 void SHOW_CURSOR(bool is_visible)
104 {
105 	/* record for our info */
106 	si->cursor.is_visible = is_visible;
107 
108 	if (is_visible)
109 		gx00_crtc_cursor_show();
110 	else
111 		gx00_crtc_cursor_hide();
112 }
113