xref: /haiku/src/add-ons/accelerants/neomagic/Cursor.c (revision 9eb55bc1d104b8fda80898f8b25c94d8000c8255)
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 	Rudolf Cornelissen 4/2003-6/2003
7 */
8 
9 #define MODULE_BIT 0x20000000
10 
11 #include "acc_std.h"
12 
13 status_t SET_CURSOR_SHAPE(uint16 width, uint16 height, uint16 hot_x, uint16 hot_y, uint8 *andMask, uint8 *xorMask)
14 {
15 	LOG(4,("SET_CURSOR_SHAPE: width %d, height %d, hot_x %d, hot_y %d\n",
16 		width, height, hot_x, hot_y));
17 
18 	if ((width != 16) || (height != 16))
19 	{
20 		return B_ERROR;
21 	}
22 	else if ((hot_x >= width) || (hot_y >= height))
23 	{
24 		return B_ERROR;
25 	}
26 	else
27 	{
28 		nm_crtc_cursor_define(andMask,xorMask);
29 
30 		/* Update cursor variables appropriately. */
31 		si->cursor.width = width;
32 		si->cursor.height = height;
33 		si->cursor.hot_x = hot_x;
34 		si->cursor.hot_y = hot_y;
35 	}
36 
37 	return B_OK;
38 }
39 
40 /* Move the cursor to the specified position on the desktop, taking account of virtual/dual issues */
41 void MOVE_CURSOR(uint16 x, uint16 y)
42 {
43 	uint16 hds = si->dm.h_display_start;	/* the current horizontal starting pixel */
44 	uint16 vds = si->dm.v_display_start;	/* the current vertical starting line */
45 	uint16 h_adjust;
46 	uint16 h_display = si->dm.timing.h_display; /* local copy needed for flatpanel */
47 	uint16 v_display = si->dm.timing.v_display; /* local copy needed for flatpanel */
48 
49 	/* clamp cursor to display */
50 	if (x >= si->dm.virtual_width) x = si->dm.virtual_width - 1;
51 	if (y >= si->dm.virtual_height) y = si->dm.virtual_height - 1;
52 
53 	/* store, for our info */
54 	si->cursor.x = x;
55 	si->cursor.y = y;
56 
57 	switch(si->dm.space)
58 	{
59 	case B_CMAP8:
60 		h_adjust = 0x03;
61 		break;
62 	case B_RGB15_LITTLE:case B_RGB16_LITTLE:
63 		h_adjust = 0x01;
64 		break;
65 	case B_RGB32_LITTLE:
66 		h_adjust = 0x00;
67 		break;
68 	default:
69 		h_adjust = 0x03;
70 		break;
71 	}
72 
73 	/* if internal panel is active correct visible screensize! */
74 	if (nm_general_output_read() & 0x02)
75 	{
76 		if (h_display > si->ps.panel_width) h_display = si->ps.panel_width;
77 		if (v_display > si->ps.panel_height) v_display = si->ps.panel_height;
78 	}
79 
80 	/* adjust h/v_display_start to move cursor onto screen */
81 	if (x >= (h_display + hds))
82 	{
83 		hds = ((x - h_display) + 1 + h_adjust) & ~h_adjust;
84 		/* make sure we stay within the display! */
85 		if ((hds + h_display) > si->dm.virtual_width)
86 			hds -= (h_adjust + 1);
87 	}
88 	else if (x < hds)
89 		hds = x & ~h_adjust;
90 
91 	if (y >= (v_display + vds))
92 		vds = y - v_display + 1;
93 	else if (y < vds)
94 		vds = y;
95 
96 	/* reposition the desktop _and_ the overlay on the display if required */
97 	if ((hds!=si->dm.h_display_start) || (vds!=si->dm.v_display_start))
98 	{
99 		MOVE_DISPLAY(hds,vds);
100 		//fixme: implement:
101 		//move_overlay(hds,vds);
102 	}
103 
104 	/* put cursor in correct physical position */
105 	if (x > (hds + si->cursor.hot_x)) x -= hds + si->cursor.hot_x;
106 	else x = 0;
107 	if (y > (vds + si->cursor.hot_y)) y -= vds + si->cursor.hot_y;
108 	else y = 0;
109 
110 	/* position the cursor on the display */
111 	nm_crtc_cursor_position(x,y);
112 }
113 
114 void SHOW_CURSOR(bool is_visible)
115 {
116 	/* record for our info */
117 	si->cursor.is_visible = is_visible;
118 
119 	if (is_visible)
120 		nm_crtc_cursor_show();
121 	else
122 		nm_crtc_cursor_hide();
123 }
124