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-8/2003 8 */ 9 10 #define MODULE_BIT 0x20000000 11 12 /*DUALHEAD notes - 13 No hardware cursor possible on the secondary head :( 14 Reasons: 15 CRTC1 has a cursor, can be displayed on DAC or MAVEN 16 CRTC2 has no cursor 17 Can not switch CRTC in one vblank (has to resync) 18 CRTC2 does not support split screen 19 app_server does not support some modes with and some without cursor 20 virtual not supported, because of MAVEN blanking issues 21 */ 22 23 #include "acc_std.h" 24 25 status_t SET_CURSOR_SHAPE(uint16 width, uint16 height, uint16 hot_x, uint16 hot_y, uint8 *andMask, uint8 *xorMask) 26 { 27 LOG(4,("SET_CURSOR_SHAPE: width %d, height %d, hot_x %d, hot_y %d\n", 28 width, height, hot_x, hot_y)); 29 30 if ((width != 16) || (height != 16)) 31 { 32 return B_ERROR; 33 } 34 else if ((hot_x >= width) || (hot_y >= height)) 35 { 36 return B_ERROR; 37 } 38 else 39 { 40 nv_crtc_cursor_define(andMask,xorMask); 41 42 /* Update cursor variables appropriately. */ 43 si->cursor.width = width; 44 si->cursor.height = height; 45 si->cursor.hot_x = hot_x; 46 si->cursor.hot_y = hot_y; 47 } 48 49 return B_OK; 50 } 51 52 /* Move the cursor to the specified position on the desktop, taking account of virtual/dual issues */ 53 void MOVE_CURSOR(uint16 x, uint16 y) 54 { 55 uint16 hds = si->dm.h_display_start; /* the current horizontal starting pixel */ 56 uint16 vds = si->dm.v_display_start; /* the current vertical starting line */ 57 uint16 h_adjust; 58 59 /* clamp cursor to display */ 60 if (x >= si->dm.virtual_width) x = si->dm.virtual_width - 1; 61 if (y >= si->dm.virtual_height) y = si->dm.virtual_height - 1; 62 63 /* store, for our info */ 64 si->cursor.x = x; 65 si->cursor.y = y; 66 67 /*set up minimum amount to scroll*/ 68 if (si->dm.flags & DUALHEAD_BITS) 69 { 70 /* fixme???? Nvidia always does pixelprecise panning on sec head?? */ 71 switch(si->dm.space) 72 { 73 case B_RGB16_LITTLE: 74 h_adjust = 0x1f; 75 break; 76 case B_RGB32_LITTLE: 77 h_adjust = 0x0f; 78 break; 79 default: 80 h_adjust = 0x1f; 81 break; 82 } 83 } 84 else 85 { 86 /* switch(si->dm.space) 87 { 88 case B_CMAP8: 89 h_adjust = 0x07; 90 break; 91 case B_RGB15_LITTLE:case B_RGB16_LITTLE: 92 h_adjust = 0x03; 93 break; 94 case B_RGB32_LITTLE: 95 h_adjust = 0x01; 96 break; 97 default: 98 h_adjust = 0x07; 99 break; 100 } 101 */ 102 /* Nvidia always does pixelprecise panning on primary head */ 103 h_adjust = 0x00; 104 } 105 106 /* adjust h/v_display_start to move cursor onto screen */ 107 switch (si->dm.flags & DUALHEAD_BITS) 108 { 109 case DUALHEAD_ON: 110 case DUALHEAD_SWITCH: 111 if (x >= ((si->dm.timing.h_display * 2) + hds)) 112 { 113 hds = ((x - (si->dm.timing.h_display * 2)) + 1 + h_adjust) & ~h_adjust; 114 /* make sure we stay within the display! */ 115 if ((hds + (si->dm.timing.h_display * 2)) > si->dm.virtual_width) 116 hds -= (h_adjust + 1); 117 } 118 else if (x < hds) 119 hds = x & ~h_adjust; 120 break; 121 default: 122 if (x >= (si->dm.timing.h_display + hds)) 123 { 124 hds = ((x - si->dm.timing.h_display) + 1 + h_adjust) & ~h_adjust; 125 /* make sure we stay within the display! */ 126 if ((hds + si->dm.timing.h_display) > si->dm.virtual_width) 127 hds -= (h_adjust + 1); 128 } 129 else if (x < hds) 130 hds = x & ~h_adjust; 131 break; 132 } 133 134 if (y >= (si->dm.timing.v_display + vds)) 135 vds = y - si->dm.timing.v_display + 1; 136 else if (y < vds) 137 vds = y; 138 139 /* reposition the desktop _and_ the overlay on the display if required */ 140 if ((hds!=si->dm.h_display_start) || (vds!=si->dm.v_display_start)) 141 { 142 MOVE_DISPLAY(hds,vds); 143 //fixme: implement: 144 //move_overlay(hds,vds); 145 } 146 147 /* put cursor in correct physical position, so stay onscreen (rel. to CRTC) */ 148 if (x > (hds + si->cursor.hot_x)) x -= (hds + si->cursor.hot_x); 149 else x = 0; 150 if (y > (vds + si->cursor.hot_y)) y -= (vds + si->cursor.hot_y); 151 else y = 0; 152 153 /* account for switched CRTC's */ 154 if (si->switched_crtcs) x -= si->dm.timing.h_display; 155 156 /* position the cursor on the display */ 157 nv_crtc_cursor_position(x,y); 158 } 159 160 void SHOW_CURSOR(bool is_visible) 161 { 162 /* record for our info */ 163 si->cursor.is_visible = is_visible; 164 165 if (is_visible) 166 nv_crtc_cursor_show(); 167 else 168 nv_crtc_cursor_hide(); 169 } 170