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 Rudolf Cornelissen 4/2003-9/2005
8 */
9
10 #define MODULE_BIT 0x20000000
11
12 #include "acc_std.h"
13
SET_CURSOR_SHAPE(uint16 width,uint16 height,uint16 hot_x,uint16 hot_y,uint8 * andMask,uint8 * xorMask)14 status_t SET_CURSOR_SHAPE(uint16 width, uint16 height, uint16 hot_x, uint16 hot_y, uint8 *andMask, uint8 *xorMask)
15 {
16 LOG(4,("SET_CURSOR_SHAPE: width %d, height %d, hot_x %d, hot_y %d\n",
17 width, height, hot_x, hot_y));
18
19 if ((width != 16) || (height != 16))
20 {
21 return B_ERROR;
22 }
23 else if ((hot_x >= width) || (hot_y >= height))
24 {
25 return B_ERROR;
26 }
27 else
28 {
29 head1_cursor_define(andMask,xorMask);
30 if ((si->dm.flags & DUALHEAD_BITS) != DUALHEAD_OFF)
31 head2_cursor_define(andMask,xorMask);
32
33 /* Update cursor variables appropriately. */
34 si->cursor.width = width;
35 si->cursor.height = height;
36 si->cursor.hot_x = hot_x;
37 si->cursor.hot_y = hot_y;
38 }
39
40 return B_OK;
41 }
42
43 /* Move the cursor to the specified position on the desktop, taking account of virtual/dual issues */
MOVE_CURSOR(uint16 x,uint16 y)44 void MOVE_CURSOR(uint16 x, uint16 y)
45 {
46 uint16 hds = si->dm.h_display_start; /* the current horizontal starting pixel */
47 uint16 vds = si->dm.v_display_start; /* the current vertical starting line */
48 uint16 h_adjust;
49
50 /* clamp cursor to display */
51 if (x >= si->dm.virtual_width) x = si->dm.virtual_width - 1;
52 if (y >= si->dm.virtual_height) y = si->dm.virtual_height - 1;
53
54 /* store, for our info */
55 si->cursor.x = x;
56 si->cursor.y = y;
57
58 /* set up minimum amount to scroll */
59 if (si->dm.flags & DUALHEAD_BITS)
60 {
61 //fixme for VIA...
62 switch(si->dm.space)
63 {
64 case B_RGB16_LITTLE:
65 h_adjust = 0x1f;
66 break;
67 case B_RGB32_LITTLE:
68 h_adjust = 0x0f;
69 break;
70 default:
71 h_adjust = 0x1f;
72 break;
73 }
74 }
75 else
76 {
77 switch(si->dm.space)
78 {
79 case B_CMAP8:
80 h_adjust = 0x07;
81 break;
82 case B_RGB15_LITTLE:case B_RGB16_LITTLE:
83 h_adjust = 0x03;
84 break;
85 case B_RGB32_LITTLE:
86 h_adjust = 0x01;
87 break;
88 default:
89 h_adjust = 0x07;
90 break;
91 }
92 }
93
94 /* adjust h/v_display_start to move cursor onto screen */
95 switch (si->dm.flags & DUALHEAD_BITS)
96 {
97 case DUALHEAD_ON:
98 case DUALHEAD_SWITCH:
99 if (x >= ((si->dm.timing.h_display * 2) + hds))
100 {
101 hds = ((x - (si->dm.timing.h_display * 2)) + 1 + h_adjust) & ~h_adjust;
102 /* make sure we stay within the display! */
103 if ((hds + (si->dm.timing.h_display * 2)) > si->dm.virtual_width)
104 hds -= (h_adjust + 1);
105 }
106 else if (x < hds)
107 hds = x & ~h_adjust;
108 break;
109 default:
110 if (x >= (si->dm.timing.h_display + hds))
111 {
112 hds = ((x - si->dm.timing.h_display) + 1 + h_adjust) & ~h_adjust;
113 /* make sure we stay within the display! */
114 if ((hds + si->dm.timing.h_display) > si->dm.virtual_width)
115 hds -= (h_adjust + 1);
116 }
117 else if (x < hds)
118 hds = x & ~h_adjust;
119 break;
120 }
121
122 if (y >= (si->dm.timing.v_display + vds))
123 vds = y - si->dm.timing.v_display + 1;
124 else if (y < vds)
125 vds = y;
126
127 /* reposition the desktop _and_ the overlay on the display if required */
128 if ((hds!=si->dm.h_display_start) || (vds!=si->dm.v_display_start))
129 {
130 MOVE_DISPLAY(hds,vds);
131 eng_bes_move_overlay();
132 }
133
134 /* put cursor in correct physical position, so stay onscreen (rel. to CRTC) */
135 if (x > (hds + si->cursor.hot_x)) x -= (hds + si->cursor.hot_x);
136 else x = 0;
137 if (y > (vds + si->cursor.hot_y)) y -= (vds + si->cursor.hot_y);
138 else y = 0;
139
140 /* position the cursor on the display */
141 switch (si->dm.flags & DUALHEAD_BITS)
142 {
143 case DUALHEAD_CLONE:
144 head1_cursor_position(x,y);
145 head2_cursor_position(x,y);
146 break;
147 case DUALHEAD_ON:
148 case DUALHEAD_SWITCH:
149 if (x < si->dm.timing.h_display)
150 {
151 if (si->cursor.dh_right)
152 {
153 LOG(4,("MOVE_CURSOR: now on left side\n"));
154 head2_cursor_hide();
155 head1_cursor_show();
156 si->cursor.dh_right = false;
157 }
158 head1_cursor_position(x, y);
159 }
160 else
161 {
162 if (!si->cursor.dh_right)
163 {
164 LOG(4,("MOVE_CURSOR: now on right side\n"));
165 head1_cursor_hide();
166 head2_cursor_show();
167 si->cursor.dh_right = true;
168 }
169 head2_cursor_position((x - si->dm.timing.h_display), y);
170 }
171 break;
172 default: /* singlehead mode */
173 head1_cursor_position(x,y);
174 break;
175 }
176 }
177
SHOW_CURSOR(bool is_visible)178 void SHOW_CURSOR(bool is_visible)
179 {
180 /* record for our info */
181 si->cursor.is_visible = is_visible;
182
183 switch (si->dm.flags & DUALHEAD_BITS)
184 {
185 case DUALHEAD_CLONE:
186 if (is_visible)
187 {
188 head1_cursor_show();
189 head2_cursor_show();
190 }
191 else
192 {
193 head1_cursor_hide();
194 head2_cursor_hide();
195 }
196 break;
197 case DUALHEAD_ON:
198 case DUALHEAD_SWITCH:
199 if (is_visible)
200 {
201 if (!si->cursor.dh_right)
202 {
203 head1_cursor_show();
204 }
205 else
206 {
207 head2_cursor_show();
208 }
209 }
210 else
211 {
212 head1_cursor_hide();
213 head2_cursor_hide();
214 }
215 break;
216 default: /* singlehead mode */
217 if (is_visible)
218 {
219 head1_cursor_show();
220 }
221 else
222 {
223 head1_cursor_hide();
224 }
225 break;
226 }
227 }
228