1 /* 2 * Copyright 2006, Haiku, Inc. 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 "HWInterface.h" 11 #include "Overlay.h" 12 13 #include <BitmapPrivate.h> 14 15 #include <InterfaceDefs.h> 16 17 18 Overlay::Overlay(HWInterface& interface) 19 : 20 fHWInterface(interface), 21 fOverlayBuffer(NULL), 22 fClientData(NULL), 23 fOverlayToken(NULL) 24 { 25 fSemaphore = create_sem(1, "overlay lock"); 26 fColor.SetColor(21, 16, 21, 16); 27 // TODO: whatever fine color we want to use here... 28 29 fWindow.offset_top = 0; 30 fWindow.offset_left = 0; 31 fWindow.offset_right = 0; 32 fWindow.offset_bottom = 0; 33 34 fWindow.flags = B_OVERLAY_COLOR_KEY; 35 } 36 37 38 Overlay::~Overlay() 39 { 40 fHWInterface.ReleaseOverlayChannel(fOverlayToken); 41 fHWInterface.FreeOverlayBuffer(fOverlayBuffer); 42 43 delete_sem(fSemaphore); 44 } 45 46 47 status_t 48 Overlay::InitCheck() const 49 { 50 return fSemaphore >= B_OK ? B_OK : fSemaphore; 51 } 52 53 54 void 55 Overlay::SetOverlayData(const overlay_buffer* overlayBuffer, 56 overlay_token token, overlay_client_data* clientData) 57 { 58 fOverlayBuffer = overlayBuffer; 59 fOverlayToken = token; 60 61 fClientData = clientData; 62 fClientData->lock = fSemaphore; 63 fClientData->buffer = (uint8*)fOverlayBuffer->buffer; 64 } 65 66 67 void 68 Overlay::SetFlags(uint32 flags) 69 { 70 if (flags & B_OVERLAY_FILTER_HORIZONTAL) 71 fWindow.flags |= B_OVERLAY_HORIZONTAL_FILTERING; 72 if (flags & B_OVERLAY_FILTER_VERTICAL) 73 fWindow.flags |= B_OVERLAY_VERTICAL_FILTERING; 74 if (flags & B_OVERLAY_MIRROR) 75 fWindow.flags |= B_OVERLAY_HORIZONTAL_MIRRORING; 76 } 77 78 79 void 80 Overlay::TakeOverToken(Overlay* other) 81 { 82 overlay_token token = other->OverlayToken(); 83 if (token == NULL) 84 return; 85 86 fOverlayToken = token; 87 //other->fOverlayToken = NULL; 88 } 89 90 91 const overlay_buffer* 92 Overlay::OverlayBuffer() const 93 { 94 return fOverlayBuffer; 95 } 96 97 98 overlay_client_data* 99 Overlay::ClientData() const 100 { 101 return fClientData; 102 } 103 104 105 overlay_token 106 Overlay::OverlayToken() const 107 { 108 return fOverlayToken; 109 } 110 111 112 void 113 Overlay::Hide() 114 { 115 if (fOverlayToken == NULL) 116 return; 117 118 fHWInterface.HideOverlay(this); 119 } 120 121 122 void 123 Overlay::SetColorSpace(uint32 colorSpace) 124 { 125 if ((fWindow.flags & B_OVERLAY_COLOR_KEY) == 0) 126 return; 127 128 uint8 colorShift = 0, greenShift = 0, alphaShift = 0; 129 rgb_color colorKey = fColor.GetColor32(); 130 131 switch (colorSpace) { 132 case B_CMAP8: 133 colorKey.red = 0xff; 134 colorKey.green = 0xff; 135 colorKey.blue = 0xff; 136 colorKey.alpha = 0xff; 137 break; 138 case B_RGB15: 139 greenShift = colorShift = 3; 140 alphaShift = 7; 141 break; 142 case B_RGB16: 143 colorShift = 3; 144 greenShift = 2; 145 alphaShift = 8; 146 break; 147 } 148 149 fWindow.red.value = colorKey.red >> colorShift; 150 fWindow.green.value = colorKey.green >> greenShift; 151 fWindow.blue.value = colorKey.blue >> colorShift; 152 fWindow.alpha.value = colorKey.alpha >> alphaShift; 153 fWindow.red.mask = 0xff >> colorShift; 154 fWindow.green.mask = 0xff >> greenShift; 155 fWindow.blue.mask = 0xff >> colorShift; 156 fWindow.alpha.mask = 0xff >> alphaShift; 157 } 158 159 160 void 161 Overlay::Configure(const BRect& source, const BRect& destination) 162 { 163 if (fOverlayToken == NULL) { 164 fOverlayToken = fHWInterface.AcquireOverlayChannel(); 165 if (fOverlayToken == NULL) 166 return; 167 } 168 169 fView.h_start = (uint16)source.left; 170 fView.v_start = (uint16)source.top; 171 fView.width = (uint16)source.IntegerWidth() + 1; 172 fView.height = (uint16)source.IntegerHeight() + 1; 173 174 fWindow.h_start = (int16)destination.left; 175 fWindow.v_start = (int16)destination.top; 176 fWindow.width = (uint16)destination.IntegerWidth() + 1; 177 fWindow.height = (uint16)destination.IntegerHeight() + 1; 178 179 fHWInterface.ConfigureOverlay(this); 180 } 181 182