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-5/2004 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 /* setting up minimum amount to scroll not needed: 59 * Nvidia cards can always do pixelprecise panning on both heads */ 60 h_adjust = 0x00; 61 62 /* adjust h/v_display_start to move cursor onto screen */ 63 switch (si->dm.flags & DUALHEAD_BITS) 64 { 65 case DUALHEAD_ON: 66 case DUALHEAD_SWITCH: 67 if (x >= ((si->dm.timing.h_display * 2) + hds)) 68 { 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); 73 } 74 else if (x < hds) 75 hds = x & ~h_adjust; 76 break; 77 default: 78 if (x >= (si->dm.timing.h_display + hds)) 79 { 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); 84 } 85 else if (x < hds) 86 hds = x & ~h_adjust; 87 break; 88 } 89 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; 94 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)) 97 { 98 MOVE_DISPLAY(hds,vds); 99 eng_bes_move_overlay(); 100 } 101 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; 107 108 /* position the cursor on the display */ 109 switch (si->dm.flags & DUALHEAD_BITS) 110 { 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) 118 { 119 if (si->cursor.dh_right) 120 { 121 LOG(4,("MOVE_CURSOR: now on left side\n")); 122 head2_cursor_hide(); 123 head1_cursor_show(); 124 si->cursor.dh_right = false; 125 } 126 head1_cursor_position(x, y); 127 } 128 else 129 { 130 if (!si->cursor.dh_right) 131 { 132 LOG(4,("MOVE_CURSOR: now on right side\n")); 133 head1_cursor_hide(); 134 head2_cursor_show(); 135 si->cursor.dh_right = true; 136 } 137 head2_cursor_position((x - si->dm.timing.h_display), y); 138 } 139 break; 140 default: /* singlehead mode */ 141 head1_cursor_position(x,y); 142 break; 143 } 144 } 145 146 void SHOW_CURSOR(bool is_visible) 147 { 148 /* record for our info */ 149 si->cursor.is_visible = is_visible; 150 151 switch (si->dm.flags & DUALHEAD_BITS) 152 { 153 case DUALHEAD_CLONE: 154 if (is_visible) 155 { 156 head1_cursor_show(); 157 head2_cursor_show(); 158 } 159 else 160 { 161 head1_cursor_hide(); 162 head2_cursor_hide(); 163 } 164 break; 165 case DUALHEAD_ON: 166 case DUALHEAD_SWITCH: 167 if (is_visible) 168 { 169 if (!si->cursor.dh_right) 170 { 171 head1_cursor_show(); 172 } 173 else 174 { 175 head2_cursor_show(); 176 } 177 } 178 else 179 { 180 head1_cursor_hide(); 181 head2_cursor_hide(); 182 } 183 break; 184 default: /* singlehead mode */ 185 if (is_visible) 186 { 187 head1_cursor_show(); 188 } 189 else 190 { 191 head1_cursor_hide(); 192 } 193 break; 194 } 195 } 196