vfs: check userland buffers before reading them.
[haiku.git] / src / add-ons / accelerants / skeleton / Cursor.c
blobf45078d3eb477152150342cfb47f74bac4893f3f
1 /*
2 Copyright 1999, Be Incorporated. All Rights Reserved.
3 This file may be used under the terms of the Be Sample Code License.
5 Other authors:
6 Mark Watson,
7 Rudolf Cornelissen 4/2003-5/2004
8 */
10 #define MODULE_BIT 0x20000000
12 #include "acc_std.h"
14 status_t SET_CURSOR_SHAPE(uint16 width, uint16 height, uint16 hot_x, uint16 hot_y, uint8 *andMask, uint8 *xorMask)
16 LOG(4,("SET_CURSOR_SHAPE: width %d, height %d, hot_x %d, hot_y %d\n",
17 width, height, hot_x, hot_y));
19 if ((width != 16) || (height != 16))
21 return B_ERROR;
23 else if ((hot_x >= width) || (hot_y >= height))
25 return B_ERROR;
27 else
29 head1_cursor_define(andMask,xorMask);
30 if ((si->dm.flags & DUALHEAD_BITS) != DUALHEAD_OFF)
31 head2_cursor_define(andMask,xorMask);
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;
40 return B_OK;
43 /* Move the cursor to the specified position on the desktop, taking account of virtual/dual issues */
44 void MOVE_CURSOR(uint16 x, uint16 y)
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;
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;
54 /* store, for our info */
55 si->cursor.x = x;
56 si->cursor.y = y;
58 /* setting up minimum amount to scroll not needed:
59 * Nvidia cards can always do pixelprecise panning on both heads */
60 h_adjust = 0x00;
62 /* adjust h/v_display_start to move cursor onto screen */
63 switch (si->dm.flags & DUALHEAD_BITS)
65 case DUALHEAD_ON:
66 case DUALHEAD_SWITCH:
67 if (x >= ((si->dm.timing.h_display * 2) + hds))
69 hds = ((x - (si->dm.timing.h_display * 2)) + 1 + h_adjust) & ~h_adjust;
70 /* make sure we stay within the display! */
71 if ((hds + (si->dm.timing.h_display * 2)) > si->dm.virtual_width)
72 hds -= (h_adjust + 1);
74 else if (x < hds)
75 hds = x & ~h_adjust;
76 break;
77 default:
78 if (x >= (si->dm.timing.h_display + hds))
80 hds = ((x - si->dm.timing.h_display) + 1 + h_adjust) & ~h_adjust;
81 /* make sure we stay within the display! */
82 if ((hds + si->dm.timing.h_display) > si->dm.virtual_width)
83 hds -= (h_adjust + 1);
85 else if (x < hds)
86 hds = x & ~h_adjust;
87 break;
90 if (y >= (si->dm.timing.v_display + vds))
91 vds = y - si->dm.timing.v_display + 1;
92 else if (y < vds)
93 vds = y;
95 /* reposition the desktop _and_ the overlay on the display if required */
96 if ((hds!=si->dm.h_display_start) || (vds!=si->dm.v_display_start))
98 MOVE_DISPLAY(hds,vds);
99 eng_bes_move_overlay();
102 /* put cursor in correct physical position, so stay onscreen (rel. to CRTC) */
103 if (x > (hds + si->cursor.hot_x)) x -= (hds + si->cursor.hot_x);
104 else x = 0;
105 if (y > (vds + si->cursor.hot_y)) y -= (vds + si->cursor.hot_y);
106 else y = 0;
108 /* position the cursor on the display */
109 switch (si->dm.flags & DUALHEAD_BITS)
111 case DUALHEAD_CLONE:
112 head1_cursor_position(x,y);
113 head2_cursor_position(x,y);
114 break;
115 case DUALHEAD_ON:
116 case DUALHEAD_SWITCH:
117 if (x < si->dm.timing.h_display)
119 if (si->cursor.dh_right)
121 LOG(4,("MOVE_CURSOR: now on left side\n"));
122 head2_cursor_hide();
123 head1_cursor_show();
124 si->cursor.dh_right = false;
126 head1_cursor_position(x, y);
128 else
130 if (!si->cursor.dh_right)
132 LOG(4,("MOVE_CURSOR: now on right side\n"));
133 head1_cursor_hide();
134 head2_cursor_show();
135 si->cursor.dh_right = true;
137 head2_cursor_position((x - si->dm.timing.h_display), y);
139 break;
140 default: /* singlehead mode */
141 head1_cursor_position(x,y);
142 break;
146 void SHOW_CURSOR(bool is_visible)
148 /* record for our info */
149 si->cursor.is_visible = is_visible;
151 switch (si->dm.flags & DUALHEAD_BITS)
153 case DUALHEAD_CLONE:
154 if (is_visible)
156 head1_cursor_show();
157 head2_cursor_show();
159 else
161 head1_cursor_hide();
162 head2_cursor_hide();
164 break;
165 case DUALHEAD_ON:
166 case DUALHEAD_SWITCH:
167 if (is_visible)
169 if (!si->cursor.dh_right)
171 head1_cursor_show();
173 else
175 head2_cursor_show();
178 else
180 head1_cursor_hide();
181 head2_cursor_hide();
183 break;
184 default: /* singlehead mode */
185 if (is_visible)
187 head1_cursor_show();
189 else
191 head1_cursor_hide();
193 break;