xref: /haiku/src/servers/app/drawing/Overlay.cpp (revision d3d8b26997fac34a84981e6d2b649521de2cc45a)
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