1 /* 2 * Copyright 2006, Haiku, Inc. All Rights Reserved. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Axel Dörfler, axeld@pinc-software.de 7 */ 8 9 10 #include "accelerant_protos.h" 11 #include "accelerant.h" 12 13 #include <string.h> 14 15 16 status_t 17 intel_set_cursor_shape(uint16 width, uint16 height, uint16 hotX, uint16 hotY, 18 uint8 *andMask, uint8 *xorMask) 19 { 20 if (width > 64 || height > 64) 21 return B_BAD_VALUE; 22 23 write32(INTEL_CURSOR_CONTROL, 0); 24 // disable cursor 25 26 // In two-color mode, the data is ordered as follows (always 64 bit per line): 27 // plane 1: line 0 (AND mask) 28 // plane 0: line 0 (XOR mask) 29 // plane 1: line 1 (AND mask) 30 // ... 31 // 32 // If the planes add to the value 0x2, the corresponding pixel is 33 // transparent, for 0x3 it inverts the background, so only the first 34 // two palette entries will be used (since we're using the 2 color mode). 35 36 uint8 *data = gInfo->cursor_memory; 37 uint8 byteWidth = (width + 7) / 8; 38 39 for (int32 y = 0; y < height; y++) { 40 for (int32 x = 0; x < byteWidth; x++) { 41 data[16 * y + x] = andMask[byteWidth * y + x]; 42 data[16 * y + x + 8] = xorMask[byteWidth * y + x]; 43 } 44 } 45 46 // We can only change the width of the pixel, but apparently 47 // not the height (or at least I couldn't figure out how), 48 // so we need to make the rest transparent 49 for (uint32 y = height; y < 64; y++) { 50 for (int32 x = 0; x < byteWidth; x++) { 51 data[16 * y + x] = 0xff; 52 data[16 * y + x + 8] = 0; 53 } 54 } 55 56 // set palette entries to white/black 57 write32(INTEL_CURSOR_PALETTE + 0, 0x00ffffff); 58 write32(INTEL_CURSOR_PALETTE + 4, 0); 59 60 gInfo->shared_info->cursor_format = CURSOR_FORMAT_2_COLORS; 61 62 write32(INTEL_CURSOR_CONTROL, CURSOR_ENABLED | gInfo->shared_info->cursor_format); 63 write32(INTEL_CURSOR_SIZE, width); 64 // TODO: I've no idea how to specify the height of the cursor - it seems to 65 // be always 64 pixels 66 67 write32(INTEL_CURSOR_BASE, (uint32)gInfo->shared_info->physical_graphics_memory 68 + gInfo->shared_info->cursor_buffer_offset); 69 70 // changing the hot point changes the cursor position, too 71 72 if (hotX != gInfo->shared_info->cursor_hot_x 73 || hotY != gInfo->shared_info->cursor_hot_y) { 74 int32 x = read32(INTEL_CURSOR_POSITION); 75 int32 y = x >> 16; 76 x &= 0xffff; 77 78 if (x & CURSOR_POSITION_NEGATIVE) 79 x = -(x & CURSOR_POSITION_MASK); 80 if (y & CURSOR_POSITION_NEGATIVE) 81 y = -(y & CURSOR_POSITION_MASK); 82 83 x += gInfo->shared_info->cursor_hot_x; 84 y += gInfo->shared_info->cursor_hot_y; 85 86 gInfo->shared_info->cursor_hot_x = hotX; 87 gInfo->shared_info->cursor_hot_y = hotY; 88 89 intel_move_cursor(x, y); 90 } 91 92 return B_OK; 93 } 94 95 96 void 97 intel_move_cursor(uint16 _x, uint16 _y) 98 { 99 int32 x = (int32)_x - gInfo->shared_info->cursor_hot_x; 100 int32 y = (int32)_y - gInfo->shared_info->cursor_hot_x; 101 102 if (x < 0) 103 x = -x | CURSOR_POSITION_NEGATIVE; 104 if (y < 0) 105 y = -y | CURSOR_POSITION_NEGATIVE; 106 107 write32(INTEL_CURSOR_POSITION, (y << 16) | x); 108 } 109 110 111 void 112 intel_show_cursor(bool isVisible) 113 { 114 if (gInfo->shared_info->cursor_visible == isVisible) 115 return; 116 117 write32(INTEL_CURSOR_CONTROL, (isVisible ? CURSOR_ENABLED : 0) 118 | gInfo->shared_info->cursor_format); 119 write32(INTEL_CURSOR_BASE, (uint32)gInfo->shared_info->physical_graphics_memory 120 + gInfo->shared_info->cursor_buffer_offset); 121 122 gInfo->shared_info->cursor_visible = isVisible; 123 } 124 125