1 /* 2 Haiku S3 Virge driver adapted from the X.org Virge driver. 3 4 Copyright (C) 1994-1999 The XFree86 Project, Inc. All Rights Reserved. 5 6 Copyright 2007-2008 Haiku, Inc. All rights reserved. 7 Distributed under the terms of the MIT license. 8 9 Authors: 10 Gerald Zajac 2007-2008 11 */ 12 13 #include "accel.h" 14 #include "virge.h" 15 16 17 18 void 19 Virge_ShowCursor(bool bShow) 20 { 21 // Turn cursor on/off. 22 23 WriteCrtcReg(0x45, bShow ? 0x01 : 0x00, 0x01); 24 } 25 26 27 void 28 Virge_SetCursorPosition(int x, int y) 29 { 30 uint8 xOffset = 0; 31 uint8 yOffset = 0; 32 33 // xOffset & yOffset are used for displaying partial cursors on screen edges. 34 35 if (x < 0) { 36 xOffset = (( -x) & 0xfe); 37 x = 0; 38 } 39 40 if (y < 0) { 41 yOffset = (( -y) & 0xfe); 42 y = 0; 43 } 44 45 // Note: when setting the cursor position, register 48 must be set last 46 // since setting register 48 activates the new cursor position. 47 48 WriteCrtcReg( 0x4e, xOffset ); 49 WriteCrtcReg( 0x4f, yOffset ); 50 51 WriteCrtcReg( 0x47, (x & 0xff) ); 52 WriteCrtcReg( 0x46, (x & 0x0700) >> 8 ); 53 54 WriteCrtcReg( 0x49, (y & 0xff) ); 55 WriteCrtcReg( 0x48, (y & 0x0700) >> 8 ); 56 } 57 58 59 bool 60 Virge_LoadCursorImage(int width, int height, uint8* andMask, uint8* xorMask) 61 { 62 SharedInfo& si = *gInfo.sharedInfo; 63 64 if (andMask == NULL || xorMask == NULL) 65 return false; 66 67 // Initialize hardware cursor to be completely transparent. 68 69 uint16* fbCursor16 = (uint16*)((addr_t)si.videoMemAddr + si.cursorOffset); 70 71 for (int i = 0; i < CURSOR_BYTES; i += 4) { 72 *fbCursor16++ = ~0; // and bits 73 *fbCursor16++ = 0; // xor bits 74 } 75 76 // Now load the AND & XOR masks for the cursor image into the cursor 77 // buffer. Note that a particular bit in these masks will have the 78 // following effect upon the corresponding cursor pixel: 79 // AND XOR Result 80 // 0 0 White pixel 81 // 0 1 Black pixel 82 // 1 0 Screen color (for transparency) 83 // 1 1 Reverse screen color to black or white 84 85 uint8* fbCursor = (uint8*)((addr_t)si.videoMemAddr + si.cursorOffset); 86 87 for (int row = 0; row < height; row++) { 88 for (int colByte = 0; colByte < width / 8; colByte++) { 89 fbCursor[row * 16 + colByte] = *andMask++; 90 fbCursor[row * 16 + colByte + 2] = *xorMask++; 91 } 92 } 93 94 // Set cursor location in video memory. 95 96 WriteCrtcReg(0x4d, (0xff & si.cursorOffset / 1024)); 97 WriteCrtcReg(0x4c, (0x0f00 & si.cursorOffset / 1024) >> 8); 98 99 // Set the cursor colors which are black foreground and white background. 100 101 ReadCrtcReg(0x45); // reset cursor color stack pointer 102 WriteCrtcReg(0x4a, 0); // set foreground color stack low, mid, high bytes 103 WriteCrtcReg(0x4a, 0); 104 WriteCrtcReg(0x4a, 0); 105 106 ReadCrtcReg(0x45); // reset cursor color stack pointer 107 WriteCrtcReg(0x4b, ~0); // set background color stack low, mid, high bytes 108 WriteCrtcReg(0x4b, ~0); 109 WriteCrtcReg(0x4b, ~0); 110 111 return true; 112 } 113