xref: /haiku/src/kits/interface/PrivateScreen.cpp (revision d9525baaf5225ccac51a32b0fb2ba5d8c0b367cf)
1a817d6adSAxel Dörfler /*
2a817d6adSAxel Dörfler  * Copyright 2002-2005, Haiku Inc.
3a817d6adSAxel Dörfler  * Distributed under the terms of the MIT License.
4a817d6adSAxel Dörfler  *
5a817d6adSAxel Dörfler  * Authors:
6a817d6adSAxel Dörfler  *		Stefano Ceccherini (burton666@libero.it)
7a817d6adSAxel Dörfler  *		Axel Dörfler, axeld@pinc-software.de
8a817d6adSAxel Dörfler  */
9a817d6adSAxel Dörfler 
10a817d6adSAxel Dörfler /**	BPrivateScreen is the class which does the real work for
11a817d6adSAxel Dörfler  *	the proxy class BScreen (it interacts with the app server).
12a817d6adSAxel Dörfler  */
13a817d6adSAxel Dörfler 
14a817d6adSAxel Dörfler 
15*d9525baaSAxel Dörfler #include "AppMisc.h"
16466871ccSAxel Dörfler #include "AppServerLink.h"
17466871ccSAxel Dörfler #include "PrivateScreen.h"
18466871ccSAxel Dörfler #include "ServerProtocol.h"
19466871ccSAxel Dörfler 
20a817d6adSAxel Dörfler #include <Autolock.h>
2116046321SStefano Ceccherini #include <Bitmap.h>
228eae8b05SStefano Ceccherini #include <Locker.h>
23624df6c6SStefano Ceccherini #include <Window.h>
24314a1024SStefano Ceccherini 
25466871ccSAxel Dörfler #include <new>
26624df6c6SStefano Ceccherini 
27466871ccSAxel Dörfler #include <stdlib.h>
2839ffb980SStefano Ceccherini 
29624df6c6SStefano Ceccherini 
30624df6c6SStefano Ceccherini // TODO: We should define this somewhere else
31624df6c6SStefano Ceccherini // We could find how R5 defines this, though it's not strictly necessary
3239ffb980SStefano Ceccherini // AFAIK, R5 here keeps also the screen width, height, colorspace, and some other things
3339ffb980SStefano Ceccherini // (it's 48 bytes big)
34624df6c6SStefano Ceccherini struct screen_desc {
35624df6c6SStefano Ceccherini 	void *base_address;
36624df6c6SStefano Ceccherini 	uint32 bytes_per_row;
37624df6c6SStefano Ceccherini };
38624df6c6SStefano Ceccherini 
39624df6c6SStefano Ceccherini 
408eae8b05SStefano Ceccherini static BPrivateScreen *sScreen;
418eae8b05SStefano Ceccherini 
428eae8b05SStefano Ceccherini // used to synchronize creation/deletion of the sScreen object
438eae8b05SStefano Ceccherini static BLocker sScreenLock("screen lock");
44624df6c6SStefano Ceccherini 
45624df6c6SStefano Ceccherini 
46ca8ed922SStefano Ceccherini using namespace BPrivate;
47ca8ed922SStefano Ceccherini 
48624df6c6SStefano Ceccherini BPrivateScreen *
49a817d6adSAxel Dörfler BPrivateScreen::CheckOut(BWindow *window)
50624df6c6SStefano Ceccherini {
51*d9525baaSAxel Dörfler 	screen_id id = B_MAIN_SCREEN_ID;
52*d9525baaSAxel Dörfler 
53*d9525baaSAxel Dörfler 	if (window != NULL) {
54*d9525baaSAxel Dörfler 		BPrivate::AppServerLink link;
55*d9525baaSAxel Dörfler 		link.StartMessage(AS_GET_SCREEN_ID_FROM_WINDOW);
56*d9525baaSAxel Dörfler 		link.Attach<int32>(_get_object_token_(window));
57*d9525baaSAxel Dörfler 
58*d9525baaSAxel Dörfler 		status_t status;
59*d9525baaSAxel Dörfler 		if (link.FlushWithReply(status) == B_OK && status == B_OK)
60*d9525baaSAxel Dörfler 			link.Read<screen_id>(&id);
61*d9525baaSAxel Dörfler 	}
62*d9525baaSAxel Dörfler 
63*d9525baaSAxel Dörfler 	return CheckOut(id);
64624df6c6SStefano Ceccherini }
65624df6c6SStefano Ceccherini 
66624df6c6SStefano Ceccherini 
67624df6c6SStefano Ceccherini BPrivateScreen *
68624df6c6SStefano Ceccherini BPrivateScreen::CheckOut(screen_id id)
69624df6c6SStefano Ceccherini {
70a817d6adSAxel Dörfler 	BAutolock locker(sScreenLock);
718eae8b05SStefano Ceccherini 
72e93cd650SStefano Ceccherini 	if (sScreen == NULL) {
7339ffb980SStefano Ceccherini 		// TODO: If we start supporting multiple monitors, we
7439ffb980SStefano Ceccherini 		// should return the right object for the given screen_id
758eae8b05SStefano Ceccherini 		sScreen = new BPrivateScreen();
768eae8b05SStefano Ceccherini 	}
778eae8b05SStefano Ceccherini 
788eae8b05SStefano Ceccherini 	return sScreen;
79624df6c6SStefano Ceccherini }
80624df6c6SStefano Ceccherini 
81624df6c6SStefano Ceccherini 
82624df6c6SStefano Ceccherini void
83624df6c6SStefano Ceccherini BPrivateScreen::Return(BPrivateScreen *screen)
84624df6c6SStefano Ceccherini {
85e93cd650SStefano Ceccherini 	// Never delete the sScreen object.
86e93cd650SStefano Ceccherini 	// system_colors() expects the colormap to be
87e93cd650SStefano Ceccherini 	// permanently stored within libbe.
88624df6c6SStefano Ceccherini }
89624df6c6SStefano Ceccherini 
90624df6c6SStefano Ceccherini 
91624df6c6SStefano Ceccherini status_t
92624df6c6SStefano Ceccherini BPrivateScreen::SetToNext()
93624df6c6SStefano Ceccherini {
94624df6c6SStefano Ceccherini 	// This function always returns B_ERROR
95624df6c6SStefano Ceccherini 	return B_ERROR;
96624df6c6SStefano Ceccherini }
97624df6c6SStefano Ceccherini 
98624df6c6SStefano Ceccherini 
99624df6c6SStefano Ceccherini color_space
100624df6c6SStefano Ceccherini BPrivateScreen::ColorSpace()
101624df6c6SStefano Ceccherini {
102624df6c6SStefano Ceccherini 	display_mode mode;
1031f41d635SStefano Ceccherini 	if (GetMode(B_CURRENT_WORKSPACE, &mode) == B_OK)
104624df6c6SStefano Ceccherini 		return (color_space)mode.space;
105624df6c6SStefano Ceccherini 
106624df6c6SStefano Ceccherini 	return B_NO_COLOR_SPACE;
107624df6c6SStefano Ceccherini }
108624df6c6SStefano Ceccherini 
109624df6c6SStefano Ceccherini 
110624df6c6SStefano Ceccherini BRect
111624df6c6SStefano Ceccherini BPrivateScreen::Frame()
112624df6c6SStefano Ceccherini {
11339ffb980SStefano Ceccherini 	// If something goes wrong, we just return this rectangle.
11439ffb980SStefano Ceccherini 	BRect rect(0, 0, 0, 0);
115624df6c6SStefano Ceccherini 	display_mode mode;
11634c39bf0SStefano Ceccherini 	if (GetMode(B_CURRENT_WORKSPACE, &mode) == B_OK)
11739ffb980SStefano Ceccherini 		rect.Set(0, 0, (float)mode.virtual_width - 1, (float)mode.virtual_height - 1);
11839ffb980SStefano Ceccherini 
11939ffb980SStefano Ceccherini 	return rect;
120624df6c6SStefano Ceccherini }
121624df6c6SStefano Ceccherini 
122624df6c6SStefano Ceccherini 
123624df6c6SStefano Ceccherini screen_id
124624df6c6SStefano Ceccherini BPrivateScreen::ID()
125624df6c6SStefano Ceccherini {
12639ffb980SStefano Ceccherini 	// TODO: Change this if we start supporting multiple screens
127624df6c6SStefano Ceccherini 	return B_MAIN_SCREEN_ID;
128624df6c6SStefano Ceccherini }
129624df6c6SStefano Ceccherini 
130624df6c6SStefano Ceccherini 
131624df6c6SStefano Ceccherini status_t
132624df6c6SStefano Ceccherini BPrivateScreen::WaitForRetrace(bigtime_t timeout)
133624df6c6SStefano Ceccherini {
134624df6c6SStefano Ceccherini 	// Get the retrace semaphore if it's the first time
135624df6c6SStefano Ceccherini 	// we are called. Cache the value then.
136624df6c6SStefano Ceccherini 	status_t status;
13710c5dab8SStefano Ceccherini 	if (fRetraceSem < 0)
138a817d6adSAxel Dörfler 		fRetraceSem = _RetraceSemaphore();
139624df6c6SStefano Ceccherini 
140624df6c6SStefano Ceccherini 	do {
141624df6c6SStefano Ceccherini 		status = acquire_sem_etc(fRetraceSem, 1, B_RELATIVE_TIMEOUT, timeout);
142624df6c6SStefano Ceccherini 	} while (status == B_INTERRUPTED);
143624df6c6SStefano Ceccherini 
144624df6c6SStefano Ceccherini 	return status;
145624df6c6SStefano Ceccherini }
146624df6c6SStefano Ceccherini 
147624df6c6SStefano Ceccherini 
148624df6c6SStefano Ceccherini uint8
149624df6c6SStefano Ceccherini BPrivateScreen::IndexForColor(uint8 red, uint8 green, uint8 blue, uint8 alpha)
150624df6c6SStefano Ceccherini {
151624df6c6SStefano Ceccherini 	// Looks like this check is necessary
152a817d6adSAxel Dörfler 	if (red == B_TRANSPARENT_COLOR.red
153a817d6adSAxel Dörfler 		&& green == B_TRANSPARENT_COLOR.green
154a817d6adSAxel Dörfler 		&& blue == B_TRANSPARENT_COLOR.blue
155a817d6adSAxel Dörfler 		&& alpha == B_TRANSPARENT_COLOR.alpha)
156624df6c6SStefano Ceccherini 		return B_TRANSPARENT_8_BIT;
157624df6c6SStefano Ceccherini 
1582e6a5805SStephan Aßmus 	uint16 index = ((blue & 0xf8) << 7) | ((green & 0xf8) << 2) | (red >> 3);
159a817d6adSAxel Dörfler 	if (ColorMap())
1602ed35bc8SStefano Ceccherini 		return fColorMap->index_map[index];
161624df6c6SStefano Ceccherini 
162624df6c6SStefano Ceccherini 	return 0;
163624df6c6SStefano Ceccherini }
164624df6c6SStefano Ceccherini 
165624df6c6SStefano Ceccherini 
166624df6c6SStefano Ceccherini rgb_color
167624df6c6SStefano Ceccherini BPrivateScreen::ColorForIndex(const uint8 index)
168624df6c6SStefano Ceccherini {
169a817d6adSAxel Dörfler 	if (ColorMap())
170624df6c6SStefano Ceccherini 		return fColorMap->color_list[index];
171624df6c6SStefano Ceccherini 
172624df6c6SStefano Ceccherini 	return rgb_color();
173624df6c6SStefano Ceccherini }
174624df6c6SStefano Ceccherini 
175624df6c6SStefano Ceccherini 
176624df6c6SStefano Ceccherini uint8
177624df6c6SStefano Ceccherini BPrivateScreen::InvertIndex(uint8 index)
178624df6c6SStefano Ceccherini {
179a817d6adSAxel Dörfler 	if (ColorMap())
180624df6c6SStefano Ceccherini 		return fColorMap->inversion_map[index];
181624df6c6SStefano Ceccherini 
182624df6c6SStefano Ceccherini 	return 0;
183624df6c6SStefano Ceccherini }
184624df6c6SStefano Ceccherini 
185624df6c6SStefano Ceccherini 
186624df6c6SStefano Ceccherini const color_map *
187624df6c6SStefano Ceccherini BPrivateScreen::ColorMap()
188624df6c6SStefano Ceccherini {
189a817d6adSAxel Dörfler 	if (fColorMap == NULL) {
190a817d6adSAxel Dörfler 		BAutolock locker(sScreenLock);
191a817d6adSAxel Dörfler 
192a817d6adSAxel Dörfler 		if (fColorMap != NULL) {
193a817d6adSAxel Dörfler 			// someone could have been faster than us
194a817d6adSAxel Dörfler 			return fColorMap;
195a817d6adSAxel Dörfler 		}
196a817d6adSAxel Dörfler 
197a817d6adSAxel Dörfler 		// TODO: BeOS R5 here gets the colormap pointer
198a817d6adSAxel Dörfler 		// (with BApplication::ro_offset_to_ptr() ?)
199a817d6adSAxel Dörfler 		// which is contained in a shared area created by the server.
200a817d6adSAxel Dörfler 		BPrivate::AppServerLink link;
201a817d6adSAxel Dörfler 		link.StartMessage(AS_SCREEN_GET_COLORMAP);
202a817d6adSAxel Dörfler 		link.Attach<screen_id>(ID());
203a817d6adSAxel Dörfler 
204a817d6adSAxel Dörfler 		status_t status;
205a817d6adSAxel Dörfler 		if (link.FlushWithReply(status) == B_OK && status == B_OK) {
206a817d6adSAxel Dörfler 			fColorMap = (color_map *)malloc(sizeof(color_map));
207a817d6adSAxel Dörfler 			fOwnsColorMap = true;
208a817d6adSAxel Dörfler 			link.Read<color_map>(fColorMap);
209a817d6adSAxel Dörfler 		}
210a817d6adSAxel Dörfler 	}
211a817d6adSAxel Dörfler 
212624df6c6SStefano Ceccherini 	return fColorMap;
213624df6c6SStefano Ceccherini }
214624df6c6SStefano Ceccherini 
215624df6c6SStefano Ceccherini 
216624df6c6SStefano Ceccherini status_t
217466871ccSAxel Dörfler BPrivateScreen::GetBitmap(BBitmap **_bitmap, bool drawCursor, BRect *bounds)
218624df6c6SStefano Ceccherini {
219466871ccSAxel Dörfler 	if (_bitmap == NULL)
22016046321SStefano Ceccherini 		return B_BAD_VALUE;
22116046321SStefano Ceccherini 
222a817d6adSAxel Dörfler 	BRect rect;
223a817d6adSAxel Dörfler 	if (bounds != NULL)
224a817d6adSAxel Dörfler 		rect = *bounds;
225a817d6adSAxel Dörfler 	else
226a817d6adSAxel Dörfler 		rect = Frame();
227a817d6adSAxel Dörfler 
228a817d6adSAxel Dörfler 	BBitmap* bitmap = new (std::nothrow) BBitmap(rect, ColorSpace());
229466871ccSAxel Dörfler 	if (bitmap == NULL)
230466871ccSAxel Dörfler 		return B_NO_MEMORY;
231466871ccSAxel Dörfler 
232466871ccSAxel Dörfler 	status_t status = bitmap->InitCheck();
233466871ccSAxel Dörfler 	if (status == B_OK)
234a817d6adSAxel Dörfler 		status = ReadBitmap(bitmap, drawCursor, &rect);
235466871ccSAxel Dörfler 	if (status != B_OK) {
236466871ccSAxel Dörfler 		delete bitmap;
237466871ccSAxel Dörfler 		return status;
238466871ccSAxel Dörfler 	}
239466871ccSAxel Dörfler 
240466871ccSAxel Dörfler 	*_bitmap = bitmap;
241466871ccSAxel Dörfler 	return B_OK;
242624df6c6SStefano Ceccherini }
243624df6c6SStefano Ceccherini 
244624df6c6SStefano Ceccherini 
245624df6c6SStefano Ceccherini status_t
246a817d6adSAxel Dörfler BPrivateScreen::ReadBitmap(BBitmap *bitmap, bool drawCursor, BRect *bounds)
247624df6c6SStefano Ceccherini {
24816046321SStefano Ceccherini 	if (bitmap == NULL)
24916046321SStefano Ceccherini 		return B_BAD_VALUE;
25016046321SStefano Ceccherini 
25116046321SStefano Ceccherini 	BRect rect;
252a817d6adSAxel Dörfler 	if (bounds != NULL)
253a817d6adSAxel Dörfler 		rect = *bounds;
25416046321SStefano Ceccherini 	else
25516046321SStefano Ceccherini 		rect = Frame();
25616046321SStefano Ceccherini 
25716046321SStefano Ceccherini 	BPrivate::AppServerLink link;
25816046321SStefano Ceccherini 	link.StartMessage(AS_READ_BITMAP);
25916046321SStefano Ceccherini 	link.Attach<int32>(bitmap->get_server_token());
26016046321SStefano Ceccherini 	link.Attach<bool>(drawCursor);
26116046321SStefano Ceccherini 	link.Attach<BRect>(rect);
26216046321SStefano Ceccherini 
263a817d6adSAxel Dörfler 	status_t status = B_ERROR;
264a817d6adSAxel Dörfler 	if (link.FlushWithReply(status) < B_OK || status != B_OK)
265a817d6adSAxel Dörfler 		return status;
26616046321SStefano Ceccherini 
26716046321SStefano Ceccherini 	return B_OK;
268624df6c6SStefano Ceccherini }
269624df6c6SStefano Ceccherini 
270624df6c6SStefano Ceccherini 
271624df6c6SStefano Ceccherini rgb_color
27239ffb980SStefano Ceccherini BPrivateScreen::DesktopColor(uint32 workspace)
273624df6c6SStefano Ceccherini {
2743ba7d6f3SAxel Dörfler 	rgb_color color = { 51, 102, 152, 255 };
275dd10337fSAxel Dörfler 	BPrivate::AppServerLink link;
2763ba7d6f3SAxel Dörfler 
2773ba7d6f3SAxel Dörfler 	link.StartMessage(AS_GET_DESKTOP_COLOR);
2783f319b33SMichael Lotz 	link.Attach<uint32>(workspace);
2793ba7d6f3SAxel Dörfler 
2803ba7d6f3SAxel Dörfler 	int32 code;
281dd10337fSAxel Dörfler 	if (link.FlushWithReply(code) == B_OK
282a817d6adSAxel Dörfler 		&& code == B_OK)
2833ba7d6f3SAxel Dörfler 		link.Read<rgb_color>(&color);
2843ba7d6f3SAxel Dörfler 
28539ffb980SStefano Ceccherini 	return color;
286624df6c6SStefano Ceccherini }
287624df6c6SStefano Ceccherini 
288624df6c6SStefano Ceccherini 
289624df6c6SStefano Ceccherini void
290a817d6adSAxel Dörfler BPrivateScreen::SetDesktopColor(rgb_color color, uint32 workspace,
291a817d6adSAxel Dörfler 	bool makeDefault)
292624df6c6SStefano Ceccherini {
293dd10337fSAxel Dörfler 	BPrivate::AppServerLink link;
2943ba7d6f3SAxel Dörfler 
2953ba7d6f3SAxel Dörfler 	link.StartMessage(AS_SET_DESKTOP_COLOR);
29639ffb980SStefano Ceccherini 	link.Attach<rgb_color>(color);
29739ffb980SStefano Ceccherini 	link.Attach<int32>(workspace);
29839ffb980SStefano Ceccherini 	link.Attach<bool>(makeDefault);
29939ffb980SStefano Ceccherini 	link.Flush();
300624df6c6SStefano Ceccherini }
301624df6c6SStefano Ceccherini 
302624df6c6SStefano Ceccherini 
303624df6c6SStefano Ceccherini status_t
304c6418981SStefano Ceccherini BPrivateScreen::ProposeMode(display_mode *target,
305c6418981SStefano Ceccherini 	const display_mode *low, const display_mode *high)
306624df6c6SStefano Ceccherini {
307c6418981SStefano Ceccherini 	// We can't return B_BAD_VALUE here, because it's used to indicate
308c6418981SStefano Ceccherini 	// that the mode returned is supported, but it doesn't fall
309c6418981SStefano Ceccherini 	// within the limit (see ProposeMode() documentation)
310c6418981SStefano Ceccherini 	if (target == NULL || low == NULL || high == NULL)
311624df6c6SStefano Ceccherini 		return B_ERROR;
312c6418981SStefano Ceccherini 
313c6418981SStefano Ceccherini 	BPrivate::AppServerLink link;
314c6418981SStefano Ceccherini 	link.StartMessage(AS_PROPOSE_MODE);
315c6418981SStefano Ceccherini 	link.Attach<screen_id>(ID());
316583f6c3eSStefano Ceccherini 	link.Attach<display_mode>(*target);
317583f6c3eSStefano Ceccherini 	link.Attach<display_mode>(*low);
318583f6c3eSStefano Ceccherini 	link.Attach<display_mode>(*high);
319583f6c3eSStefano Ceccherini 
320c6418981SStefano Ceccherini 	status_t status = B_ERROR;
321a817d6adSAxel Dörfler 	if (link.FlushWithReply(status) == B_OK && status == B_OK) {
322c6418981SStefano Ceccherini 		link.Read<display_mode>(target);
323a817d6adSAxel Dörfler 
324a817d6adSAxel Dörfler 		bool withinLimits;
325a817d6adSAxel Dörfler 		link.Read<bool>(&withinLimits);
326a817d6adSAxel Dörfler 		if (!withinLimits)
327a817d6adSAxel Dörfler 			status = B_BAD_VALUE;
328c6418981SStefano Ceccherini 	}
329c6418981SStefano Ceccherini 
330c6418981SStefano Ceccherini 	return status;
331624df6c6SStefano Ceccherini }
332624df6c6SStefano Ceccherini 
333624df6c6SStefano Ceccherini 
334624df6c6SStefano Ceccherini status_t
335a817d6adSAxel Dörfler BPrivateScreen::GetModeList(display_mode **_modeList, uint32 *_count)
336624df6c6SStefano Ceccherini {
337a817d6adSAxel Dörfler 	if (_modeList == NULL || _count == NULL)
33810c5dab8SStefano Ceccherini 		return B_BAD_VALUE;
33910c5dab8SStefano Ceccherini 
34010c5dab8SStefano Ceccherini 	BPrivate::AppServerLink link;
34110c5dab8SStefano Ceccherini 	link.StartMessage(AS_GET_MODE_LIST);
34210c5dab8SStefano Ceccherini 	link.Attach<screen_id>(ID());
343a817d6adSAxel Dörfler 
344a817d6adSAxel Dörfler 	status_t status = B_ERROR;
345a817d6adSAxel Dörfler 	if (link.FlushWithReply(status) == B_OK && status == B_OK) {
346a817d6adSAxel Dörfler 		link.Read<uint32>(_count);
347a817d6adSAxel Dörfler 		// TODO: this could get too big for the link
348a817d6adSAxel Dörfler 		int32 size = *_count * sizeof(display_mode);
349a817d6adSAxel Dörfler 		*_modeList = (display_mode *)malloc(size);
350a817d6adSAxel Dörfler 		if (_modeList == NULL)
351a817d6adSAxel Dörfler 			return B_NO_MEMORY;
352a817d6adSAxel Dörfler 
353a817d6adSAxel Dörfler 		link.Read(*_modeList, size);
35410c5dab8SStefano Ceccherini 	}
35510c5dab8SStefano Ceccherini 
35610c5dab8SStefano Ceccherini 	return status;
357624df6c6SStefano Ceccherini }
358624df6c6SStefano Ceccherini 
359624df6c6SStefano Ceccherini 
360624df6c6SStefano Ceccherini status_t
361624df6c6SStefano Ceccherini BPrivateScreen::GetMode(uint32 workspace, display_mode *mode)
362624df6c6SStefano Ceccherini {
363314a1024SStefano Ceccherini 	if (mode == NULL)
364314a1024SStefano Ceccherini 		return B_BAD_VALUE;
365314a1024SStefano Ceccherini 
366dd10337fSAxel Dörfler 	BPrivate::AppServerLink link;
36734c39bf0SStefano Ceccherini 	link.StartMessage(AS_SCREEN_GET_MODE);
36834c39bf0SStefano Ceccherini 	link.Attach<screen_id>(ID());
36939ffb980SStefano Ceccherini 	link.Attach<uint32>(workspace);
370fca6492fSStefano Ceccherini 
37134c39bf0SStefano Ceccherini 	status_t status = B_ERROR;
372a817d6adSAxel Dörfler 	if (link.FlushWithReply(status) != B_OK
373a817d6adSAxel Dörfler 		|| status != B_OK)
37439ffb980SStefano Ceccherini 		return status;
375a817d6adSAxel Dörfler 
376a817d6adSAxel Dörfler 	link.Read<display_mode>(mode);
377a817d6adSAxel Dörfler 	return B_OK;
378624df6c6SStefano Ceccherini }
379624df6c6SStefano Ceccherini 
380624df6c6SStefano Ceccherini 
381624df6c6SStefano Ceccherini status_t
382624df6c6SStefano Ceccherini BPrivateScreen::SetMode(uint32 workspace, display_mode *mode, bool makeDefault)
383624df6c6SStefano Ceccherini {
384314a1024SStefano Ceccherini 	if (mode == NULL)
385314a1024SStefano Ceccherini 		return B_BAD_VALUE;
386314a1024SStefano Ceccherini 
387dd10337fSAxel Dörfler 	BPrivate::AppServerLink link;
388314a1024SStefano Ceccherini 	link.StartMessage(AS_SCREEN_SET_MODE);
389314a1024SStefano Ceccherini 	link.Attach<screen_id>(ID());
39039ffb980SStefano Ceccherini 	link.Attach<uint32>(workspace);
39139ffb980SStefano Ceccherini 	link.Attach<display_mode>(*mode);
39239ffb980SStefano Ceccherini 	link.Attach<bool>(makeDefault);
393314a1024SStefano Ceccherini 
394314a1024SStefano Ceccherini 	status_t status = B_ERROR;
395a817d6adSAxel Dörfler 	link.FlushWithReply(status);
396314a1024SStefano Ceccherini 
39739ffb980SStefano Ceccherini 	return status;
398624df6c6SStefano Ceccherini }
399624df6c6SStefano Ceccherini 
400624df6c6SStefano Ceccherini 
401624df6c6SStefano Ceccherini status_t
402624df6c6SStefano Ceccherini BPrivateScreen::GetDeviceInfo(accelerant_device_info *info)
403624df6c6SStefano Ceccherini {
404c6418981SStefano Ceccherini 	if (info == NULL)
405c6418981SStefano Ceccherini 		return B_BAD_VALUE;
406c6418981SStefano Ceccherini 
407c6418981SStefano Ceccherini 	BPrivate::AppServerLink link;
408c6418981SStefano Ceccherini 	link.StartMessage(AS_GET_ACCELERANT_INFO);
409c6418981SStefano Ceccherini 	link.Attach<screen_id>(ID());
410a817d6adSAxel Dörfler 
411a817d6adSAxel Dörfler 	status_t status = B_ERROR;
412a817d6adSAxel Dörfler 	if (link.FlushWithReply(status) == B_OK && status == B_OK) {
413c6418981SStefano Ceccherini 		link.Read<accelerant_device_info>(info);
414c6418981SStefano Ceccherini 		return B_OK;
415c6418981SStefano Ceccherini 	}
416c6418981SStefano Ceccherini 
417a817d6adSAxel Dörfler 	return status;
418624df6c6SStefano Ceccherini }
419624df6c6SStefano Ceccherini 
420624df6c6SStefano Ceccherini 
421624df6c6SStefano Ceccherini status_t
422624df6c6SStefano Ceccherini BPrivateScreen::GetPixelClockLimits(display_mode *mode, uint32 *low, uint32 *high)
423624df6c6SStefano Ceccherini {
42475de27f8SStefano Ceccherini 	if (mode == NULL || low == NULL || high == NULL)
42575de27f8SStefano Ceccherini 		return B_BAD_VALUE;
42675de27f8SStefano Ceccherini 
42775de27f8SStefano Ceccherini 	BPrivate::AppServerLink link;
42875de27f8SStefano Ceccherini 	link.StartMessage(AS_GET_PIXEL_CLOCK_LIMITS);
42975de27f8SStefano Ceccherini 	link.Attach<screen_id>(ID());
43075de27f8SStefano Ceccherini 	link.Attach<display_mode>(*mode);
43175de27f8SStefano Ceccherini 
432a817d6adSAxel Dörfler 	status_t status;
433a817d6adSAxel Dörfler 	if (link.FlushWithReply(status) == B_OK && status == B_OK) {
43475de27f8SStefano Ceccherini 		link.Read<uint32>(low);
43575de27f8SStefano Ceccherini 		link.Read<uint32>(high);
43675de27f8SStefano Ceccherini 		return B_OK;
43775de27f8SStefano Ceccherini 	}
43875de27f8SStefano Ceccherini 
439a817d6adSAxel Dörfler 	return status;
440624df6c6SStefano Ceccherini }
441624df6c6SStefano Ceccherini 
442624df6c6SStefano Ceccherini 
443624df6c6SStefano Ceccherini status_t
444a817d6adSAxel Dörfler BPrivateScreen::GetTimingConstraints(display_timing_constraints *constraints)
445624df6c6SStefano Ceccherini {
446a817d6adSAxel Dörfler 	if (constraints == NULL)
44755b222b0SStefano Ceccherini 		return B_BAD_VALUE;
44855b222b0SStefano Ceccherini 
44975de27f8SStefano Ceccherini 	BPrivate::AppServerLink link;
45075de27f8SStefano Ceccherini 	link.StartMessage(AS_GET_TIMING_CONSTRAINTS);
45175de27f8SStefano Ceccherini 	link.Attach<screen_id>(ID());
45275de27f8SStefano Ceccherini 
453a817d6adSAxel Dörfler 	status_t status = B_ERROR;
454a817d6adSAxel Dörfler 	if (link.FlushWithReply(status) == B_OK && status == B_OK) {
455a817d6adSAxel Dörfler 		link.Read<display_timing_constraints>(constraints);
45675de27f8SStefano Ceccherini 		return B_OK;
45775de27f8SStefano Ceccherini 	}
45875de27f8SStefano Ceccherini 
459a817d6adSAxel Dörfler 	return status;
460624df6c6SStefano Ceccherini }
461624df6c6SStefano Ceccherini 
462624df6c6SStefano Ceccherini 
463624df6c6SStefano Ceccherini status_t
464624df6c6SStefano Ceccherini BPrivateScreen::SetDPMS(uint32 dpmsState)
465624df6c6SStefano Ceccherini {
466dd10337fSAxel Dörfler 	BPrivate::AppServerLink link;
46755b222b0SStefano Ceccherini 	link.StartMessage(AS_SET_DPMS);
46839ffb980SStefano Ceccherini 	link.Attach<screen_id>(ID());
46939ffb980SStefano Ceccherini 	link.Attach<uint32>(dpmsState);
47055b222b0SStefano Ceccherini 
471a817d6adSAxel Dörfler 	status_t status = B_ERROR;
472a817d6adSAxel Dörfler 	link.FlushWithReply(status);
473a817d6adSAxel Dörfler 
474a817d6adSAxel Dörfler 	return status;
475624df6c6SStefano Ceccherini }
476624df6c6SStefano Ceccherini 
477624df6c6SStefano Ceccherini 
478624df6c6SStefano Ceccherini uint32
479624df6c6SStefano Ceccherini BPrivateScreen::DPMSState()
480624df6c6SStefano Ceccherini {
48139ffb980SStefano Ceccherini 	uint32 state = 0;
48255b222b0SStefano Ceccherini 
483dd10337fSAxel Dörfler 	BPrivate::AppServerLink link;
48455b222b0SStefano Ceccherini 	link.StartMessage(AS_GET_DPMS_STATE);
48539ffb980SStefano Ceccherini 	link.Attach<screen_id>(ID());
486a817d6adSAxel Dörfler 
487a817d6adSAxel Dörfler 	status_t status;
488a817d6adSAxel Dörfler 	if (link.FlushWithReply(status) == B_OK && status == B_OK)
48955b222b0SStefano Ceccherini 		link.Read<uint32>(&state);
49055b222b0SStefano Ceccherini 
49139ffb980SStefano Ceccherini 	return state;
492624df6c6SStefano Ceccherini }
493624df6c6SStefano Ceccherini 
494624df6c6SStefano Ceccherini 
495624df6c6SStefano Ceccherini uint32
496624df6c6SStefano Ceccherini BPrivateScreen::DPMSCapabilites()
497624df6c6SStefano Ceccherini {
49839ffb980SStefano Ceccherini 	uint32 capabilities = 0;
49955b222b0SStefano Ceccherini 
500dd10337fSAxel Dörfler 	BPrivate::AppServerLink link;
50155b222b0SStefano Ceccherini 	link.StartMessage(AS_GET_DPMS_CAPABILITIES);
50239ffb980SStefano Ceccherini 	link.Attach<screen_id>(ID());
503a817d6adSAxel Dörfler 
504a817d6adSAxel Dörfler 	status_t status;
505a817d6adSAxel Dörfler 	if (link.FlushWithReply(status) == B_OK && status == B_OK)
50655b222b0SStefano Ceccherini 		link.Read<uint32>(&capabilities);
50755b222b0SStefano Ceccherini 
50839ffb980SStefano Ceccherini 	return capabilities;
509624df6c6SStefano Ceccherini }
510624df6c6SStefano Ceccherini 
511624df6c6SStefano Ceccherini 
512624df6c6SStefano Ceccherini void *
513624df6c6SStefano Ceccherini BPrivateScreen::BaseAddress()
514624df6c6SStefano Ceccherini {
515624df6c6SStefano Ceccherini 	screen_desc desc;
516624df6c6SStefano Ceccherini 	if (get_screen_desc(&desc) == B_OK)
517624df6c6SStefano Ceccherini 		return desc.base_address;
518624df6c6SStefano Ceccherini 
519624df6c6SStefano Ceccherini 	return NULL;
520624df6c6SStefano Ceccherini }
521624df6c6SStefano Ceccherini 
522624df6c6SStefano Ceccherini 
523624df6c6SStefano Ceccherini uint32
524624df6c6SStefano Ceccherini BPrivateScreen::BytesPerRow()
525624df6c6SStefano Ceccherini {
526624df6c6SStefano Ceccherini 	screen_desc desc;
527624df6c6SStefano Ceccherini 	if (get_screen_desc(&desc) == B_OK)
528624df6c6SStefano Ceccherini 		return desc.bytes_per_row;
529a817d6adSAxel Dörfler 
530624df6c6SStefano Ceccherini 	return 0;
531624df6c6SStefano Ceccherini }
532624df6c6SStefano Ceccherini 
533624df6c6SStefano Ceccherini 
534624df6c6SStefano Ceccherini status_t
535624df6c6SStefano Ceccherini BPrivateScreen::get_screen_desc(screen_desc *desc)
536624df6c6SStefano Ceccherini {
53739ffb980SStefano Ceccherini 	status_t status = B_ERROR;
53839ffb980SStefano Ceccherini 	/*
539dd10337fSAxel Dörfler 	BPrivate::AppServerLink link;
54039ffb980SStefano Ceccherini 	PortMessage reply;
54139ffb980SStefano Ceccherini 	link.SetOpCode(AS_GET_SCREEN_DESC);
54239ffb980SStefano Ceccherini 	link.Attach<screen_id>(ID());
54339ffb980SStefano Ceccherini 	link.FlushWithReply(&reply);
54439ffb980SStefano Ceccherini 	reply.Read<screen_desc>(*desc);
54539ffb980SStefano Ceccherini 	reply.Read<status_t>(&status);
54639ffb980SStefano Ceccherini 	*/
54739ffb980SStefano Ceccherini 	return status;
548624df6c6SStefano Ceccherini }
549624df6c6SStefano Ceccherini 
550624df6c6SStefano Ceccherini 
551a817d6adSAxel Dörfler // #pragma mark - private methods
55275de27f8SStefano Ceccherini 
553a817d6adSAxel Dörfler 
554a817d6adSAxel Dörfler sem_id
555a817d6adSAxel Dörfler BPrivateScreen::_RetraceSemaphore()
556a817d6adSAxel Dörfler {
55775de27f8SStefano Ceccherini 	BPrivate::AppServerLink link;
55875de27f8SStefano Ceccherini 	link.StartMessage(AS_GET_RETRACE_SEMAPHORE);
55975de27f8SStefano Ceccherini 	link.Attach<screen_id>(ID());
560a817d6adSAxel Dörfler 
561a817d6adSAxel Dörfler 	sem_id id = B_BAD_SEM_ID;
562a817d6adSAxel Dörfler 	link.FlushWithReply(id);
56375de27f8SStefano Ceccherini 
56475de27f8SStefano Ceccherini 	return id;
56575de27f8SStefano Ceccherini }
56675de27f8SStefano Ceccherini 
56775de27f8SStefano Ceccherini 
568624df6c6SStefano Ceccherini BPrivateScreen::BPrivateScreen()
569624df6c6SStefano Ceccherini 	:
570624df6c6SStefano Ceccherini 	fColorMap(NULL),
571624df6c6SStefano Ceccherini 	fRetraceSem(-1),
572624df6c6SStefano Ceccherini 	fOwnsColorMap(false)
573624df6c6SStefano Ceccherini {
574624df6c6SStefano Ceccherini }
575624df6c6SStefano Ceccherini 
576624df6c6SStefano Ceccherini 
577624df6c6SStefano Ceccherini BPrivateScreen::~BPrivateScreen()
578624df6c6SStefano Ceccherini {
579624df6c6SStefano Ceccherini 	if (fOwnsColorMap)
580624df6c6SStefano Ceccherini 		free(fColorMap);
581624df6c6SStefano Ceccherini }
582