RemoteDesktop: Implement support for BAffineTransform.
[haiku.git] / src / servers / app / drawing / Overlay.cpp
blobdd527cd50f37e6c51879113ef6b927a5e2af5e37
1 /*
2 * Copyright 2006-2009, Haiku, Inc.
3 * Distributed under the terms of the MIT License.
5 * Authors:
6 * Axel Dörfler, axeld@pinc-software.de
7 */
10 #include "Overlay.h"
12 #include <BitmapPrivate.h>
14 #include "HWInterface.h"
15 #include "ServerBitmap.h"
18 //#define TRACE_OVERLAY
19 #ifdef TRACE_OVERLAY
20 # define TRACE(x...) ktrace_printf(x);
21 #else
22 # define TRACE(x...) ;
23 #endif
26 const static bigtime_t kOverlayTimeout = 1000000LL;
27 // after 1 second, the team holding the lock will be killed
29 class SemaphoreLocker {
30 public:
31 SemaphoreLocker(sem_id semaphore, bigtime_t timeout = B_INFINITE_TIMEOUT)
33 fSemaphore(semaphore)
35 do {
36 fStatus = acquire_sem_etc(fSemaphore, 1, B_RELATIVE_TIMEOUT,
37 timeout);
38 } while (fStatus == B_INTERRUPTED);
41 ~SemaphoreLocker()
43 if (fStatus == B_OK)
44 release_sem_etc(fSemaphore, 1, B_DO_NOT_RESCHEDULE);
47 status_t LockStatus()
49 return fStatus;
52 private:
53 sem_id fSemaphore;
54 status_t fStatus;
58 // #pragma mark -
61 Overlay::Overlay(HWInterface& interface, ServerBitmap* bitmap,
62 overlay_token token)
64 fHWInterface(interface),
65 fOverlayBuffer(NULL),
66 fClientData(NULL),
67 fOverlayToken(token)
69 fSemaphore = create_sem(1, "overlay lock");
70 fColor = (rgb_color){ 0, 80, 0, 0 };
71 // TODO: whatever fine color we want to use here...
73 fWindow.offset_top = 0;
74 fWindow.offset_left = 0;
75 fWindow.offset_right = 0;
76 fWindow.offset_bottom = 0;
78 fWindow.flags = B_OVERLAY_COLOR_KEY;
80 _AllocateBuffer(bitmap);
82 TRACE("overlay: created %p, bitmap %p\n", this, bitmap);
86 Overlay::~Overlay()
88 fHWInterface.ReleaseOverlayChannel(fOverlayToken);
89 _FreeBuffer();
91 delete_sem(fSemaphore);
92 TRACE("overlay: deleted %p\n", this);
96 status_t
97 Overlay::InitCheck() const
99 if (fSemaphore < B_OK)
100 return fSemaphore;
102 if (fOverlayBuffer == NULL)
103 return B_NO_MEMORY;
105 return B_OK;
109 status_t
110 Overlay::Resume(ServerBitmap* bitmap)
112 SemaphoreLocker locker(fSemaphore, kOverlayTimeout);
113 if (locker.LockStatus() == B_TIMED_OUT) {
114 // TODO: kill app!
117 TRACE("overlay: resume %p (lock status %ld)\n", this, locker.LockStatus());
119 status_t status = _AllocateBuffer(bitmap);
120 if (status < B_OK)
121 return status;
123 fClientData->buffer = (uint8*)fOverlayBuffer->buffer;
124 return B_OK;
128 status_t
129 Overlay::Suspend(ServerBitmap* bitmap, bool needTemporary)
131 SemaphoreLocker locker(fSemaphore, kOverlayTimeout);
132 if (locker.LockStatus() == B_TIMED_OUT) {
133 // TODO: kill app!
136 TRACE("overlay: suspend %p (lock status %ld)\n", this, locker.LockStatus());
138 _FreeBuffer();
139 fClientData->buffer = NULL;
141 return B_OK;
145 void
146 Overlay::_FreeBuffer()
148 fHWInterface.FreeOverlayBuffer(fOverlayBuffer);
149 fOverlayBuffer = NULL;
153 status_t
154 Overlay::_AllocateBuffer(ServerBitmap* bitmap)
156 fOverlayBuffer = fHWInterface.AllocateOverlayBuffer(bitmap->Width(),
157 bitmap->Height(), bitmap->ColorSpace());
158 if (fOverlayBuffer == NULL)
159 return B_NO_MEMORY;
161 return B_OK;
165 void
166 Overlay::SetClientData(overlay_client_data* clientData)
168 fClientData = clientData;
169 fClientData->lock = fSemaphore;
170 fClientData->buffer = (uint8*)fOverlayBuffer->buffer;
174 void
175 Overlay::SetFlags(uint32 flags)
177 if (flags & B_OVERLAY_FILTER_HORIZONTAL)
178 fWindow.flags |= B_OVERLAY_HORIZONTAL_FILTERING;
179 if (flags & B_OVERLAY_FILTER_VERTICAL)
180 fWindow.flags |= B_OVERLAY_VERTICAL_FILTERING;
181 if (flags & B_OVERLAY_MIRROR)
182 fWindow.flags |= B_OVERLAY_HORIZONTAL_MIRRORING;
186 void
187 Overlay::TakeOverToken(Overlay* other)
189 overlay_token token = other->OverlayToken();
190 if (token == NULL)
191 return;
193 fOverlayToken = token;
194 //other->fOverlayToken = NULL;
198 const overlay_buffer*
199 Overlay::OverlayBuffer() const
201 return fOverlayBuffer;
205 overlay_client_data*
206 Overlay::ClientData() const
208 return fClientData;
212 overlay_token
213 Overlay::OverlayToken() const
215 return fOverlayToken;
219 void
220 Overlay::Hide()
222 if (fOverlayToken == NULL)
223 return;
225 fHWInterface.HideOverlay(this);
226 TRACE("overlay: hide %p\n", this);
230 void
231 Overlay::SetColorSpace(uint32 colorSpace)
233 if ((fWindow.flags & B_OVERLAY_COLOR_KEY) == 0)
234 return;
236 uint8 colorShift = 0, greenShift = 0, alphaShift = 0;
237 rgb_color colorKey = fColor;
239 switch (colorSpace) {
240 case B_RGB15:
241 greenShift = colorShift = 3;
242 alphaShift = 7;
243 break;
244 case B_RGB16:
245 colorShift = 3;
246 greenShift = 2;
247 alphaShift = 8;
248 break;
251 fWindow.red.value = colorKey.red >> colorShift;
252 fWindow.green.value = colorKey.green >> greenShift;
253 fWindow.blue.value = colorKey.blue >> colorShift;
254 fWindow.alpha.value = colorKey.alpha >> alphaShift;
255 fWindow.red.mask = 0xff >> colorShift;
256 fWindow.green.mask = 0xff >> greenShift;
257 fWindow.blue.mask = 0xff >> colorShift;
258 fWindow.alpha.mask = 0xff >> alphaShift;
262 void
263 Overlay::Configure(const BRect& source, const BRect& destination)
265 if (fOverlayToken == NULL) {
266 fOverlayToken = fHWInterface.AcquireOverlayChannel();
267 if (fOverlayToken == NULL)
268 return;
271 TRACE("overlay: configure %p\n", this);
273 fView.h_start = (uint16)source.left;
274 fView.v_start = (uint16)source.top;
275 fView.width = (uint16)source.IntegerWidth() + 1;
276 fView.height = (uint16)source.IntegerHeight() + 1;
278 fWindow.h_start = (int16)destination.left;
279 fWindow.v_start = (int16)destination.top;
280 fWindow.width = (uint16)destination.IntegerWidth() + 1;
281 fWindow.height = (uint16)destination.IntegerHeight() + 1;
283 fHWInterface.ConfigureOverlay(this);