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 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 */ 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 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