xref: /haiku/src/kits/interface/PrivateScreen.cpp (revision 466871cc9312e373b9fa698cd1e28587b06702f4)
1624df6c6SStefano Ceccherini //------------------------------------------------------------------------------
21f41d635SStefano Ceccherini //	Copyright (c) 2002-2005, Haiku
3624df6c6SStefano Ceccherini //
4624df6c6SStefano Ceccherini //	Permission is hereby granted, free of charge, to any person obtaining a
5624df6c6SStefano Ceccherini //	copy of this software and associated documentation files (the "Software"),
6624df6c6SStefano Ceccherini //	to deal in the Software without restriction, including without limitation
7624df6c6SStefano Ceccherini //	the rights to use, copy, modify, merge, publish, distribute, sublicense,
8624df6c6SStefano Ceccherini //	and/or sell copies of the Software, and to permit persons to whom the
9624df6c6SStefano Ceccherini //	Software is furnished to do so, subject to the following conditions:
10624df6c6SStefano Ceccherini //
11624df6c6SStefano Ceccherini //	The above copyright notice and this permission notice shall be included in
12624df6c6SStefano Ceccherini //	all copies or substantial portions of the Software.
13624df6c6SStefano Ceccherini //
14624df6c6SStefano Ceccherini //	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15624df6c6SStefano Ceccherini //	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16624df6c6SStefano Ceccherini //	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17624df6c6SStefano Ceccherini //	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18624df6c6SStefano Ceccherini //	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19624df6c6SStefano Ceccherini //	FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20624df6c6SStefano Ceccherini //	DEALINGS IN THE SOFTWARE.
21624df6c6SStefano Ceccherini //
22624df6c6SStefano Ceccherini //	File Name:		PrivateScreen.cpp
23624df6c6SStefano Ceccherini //	Author:			Stefano Ceccherini (burton666@libero.it)
24624df6c6SStefano Ceccherini //	Description:	BPrivateScreen is the class which does the real work
25624df6c6SStefano Ceccherini //					for the proxy class BScreen (it interacts with the app server).
26624df6c6SStefano Ceccherini //------------------------------------------------------------------------------
27*466871ccSAxel Dörfler #include "AppServerLink.h"
28*466871ccSAxel Dörfler #include "PrivateScreen.h"
29*466871ccSAxel Dörfler #include "ServerProtocol.h"
30*466871ccSAxel Dörfler 
3116046321SStefano Ceccherini #include <Bitmap.h>
328eae8b05SStefano Ceccherini #include <Locker.h>
33624df6c6SStefano Ceccherini #include <Window.h>
34314a1024SStefano Ceccherini 
35*466871ccSAxel Dörfler #include <new>
36624df6c6SStefano Ceccherini 
37*466871ccSAxel Dörfler #include <stdlib.h>
3839ffb980SStefano Ceccherini 
39624df6c6SStefano Ceccherini 
40624df6c6SStefano Ceccherini // TODO: We should define this somewhere else
41624df6c6SStefano Ceccherini // We could find how R5 defines this, though it's not strictly necessary
4239ffb980SStefano Ceccherini // AFAIK, R5 here keeps also the screen width, height, colorspace, and some other things
4339ffb980SStefano Ceccherini // (it's 48 bytes big)
44624df6c6SStefano Ceccherini struct screen_desc {
45624df6c6SStefano Ceccherini 	void *base_address;
46624df6c6SStefano Ceccherini 	uint32 bytes_per_row;
47624df6c6SStefano Ceccherini };
48624df6c6SStefano Ceccherini 
49624df6c6SStefano Ceccherini 
508eae8b05SStefano Ceccherini static BPrivateScreen *sScreen;
518eae8b05SStefano Ceccherini 
528eae8b05SStefano Ceccherini // used to synchronize creation/deletion of the sScreen object
538eae8b05SStefano Ceccherini static BLocker sScreenLock("screen lock");
54624df6c6SStefano Ceccherini 
55624df6c6SStefano Ceccherini 
56ca8ed922SStefano Ceccherini using namespace BPrivate;
57ca8ed922SStefano Ceccherini 
58624df6c6SStefano Ceccherini BPrivateScreen *
59624df6c6SStefano Ceccherini BPrivateScreen::CheckOut(BWindow *win)
60624df6c6SStefano Ceccherini {
618eae8b05SStefano Ceccherini 	sScreenLock.Lock();
628eae8b05SStefano Ceccherini 
63e93cd650SStefano Ceccherini 	if (sScreen == NULL) {
6439ffb980SStefano Ceccherini 		// TODO: If we start supporting multiple monitors, we
6539ffb980SStefano Ceccherini 		// should return the right screen for the passed BWindow
668eae8b05SStefano Ceccherini 		sScreen = new BPrivateScreen();
678eae8b05SStefano Ceccherini 	}
688eae8b05SStefano Ceccherini 
698eae8b05SStefano Ceccherini 	sScreenLock.Unlock();
708eae8b05SStefano Ceccherini 
718eae8b05SStefano Ceccherini 	return sScreen;
72624df6c6SStefano Ceccherini }
73624df6c6SStefano Ceccherini 
74624df6c6SStefano Ceccherini 
75624df6c6SStefano Ceccherini BPrivateScreen *
76624df6c6SStefano Ceccherini BPrivateScreen::CheckOut(screen_id id)
77624df6c6SStefano Ceccherini {
788eae8b05SStefano Ceccherini 	sScreenLock.Lock();
798eae8b05SStefano Ceccherini 
80e93cd650SStefano Ceccherini 	if (sScreen == NULL) {
8139ffb980SStefano Ceccherini 		// TODO: If we start supporting multiple monitors, we
8239ffb980SStefano Ceccherini 		// should return the right object for the given screen_id
838eae8b05SStefano Ceccherini 		sScreen = new BPrivateScreen();
848eae8b05SStefano Ceccherini 	}
858eae8b05SStefano Ceccherini 
868eae8b05SStefano Ceccherini 	sScreenLock.Unlock();
878eae8b05SStefano Ceccherini 
888eae8b05SStefano Ceccherini 	return sScreen;
89624df6c6SStefano Ceccherini }
90624df6c6SStefano Ceccherini 
91624df6c6SStefano Ceccherini 
92624df6c6SStefano Ceccherini void
93624df6c6SStefano Ceccherini BPrivateScreen::Return(BPrivateScreen *screen)
94624df6c6SStefano Ceccherini {
95e93cd650SStefano Ceccherini 	// Never delete the sScreen object.
96e93cd650SStefano Ceccherini 	// system_colors() expects the colormap to be
97e93cd650SStefano Ceccherini 	// permanently stored within libbe.
98624df6c6SStefano Ceccherini }
99624df6c6SStefano Ceccherini 
100624df6c6SStefano Ceccherini 
101624df6c6SStefano Ceccherini status_t
102624df6c6SStefano Ceccherini BPrivateScreen::SetToNext()
103624df6c6SStefano Ceccherini {
104624df6c6SStefano Ceccherini 	// This function always returns B_ERROR
105624df6c6SStefano Ceccherini 	return B_ERROR;
106624df6c6SStefano Ceccherini }
107624df6c6SStefano Ceccherini 
108624df6c6SStefano Ceccherini 
109624df6c6SStefano Ceccherini color_space
110624df6c6SStefano Ceccherini BPrivateScreen::ColorSpace()
111624df6c6SStefano Ceccherini {
112624df6c6SStefano Ceccherini 	display_mode mode;
1131f41d635SStefano Ceccherini 	if (GetMode(B_CURRENT_WORKSPACE, &mode) == B_OK)
114624df6c6SStefano Ceccherini 		return (color_space)mode.space;
115624df6c6SStefano Ceccherini 
116624df6c6SStefano Ceccherini 	return B_NO_COLOR_SPACE;
117624df6c6SStefano Ceccherini }
118624df6c6SStefano Ceccherini 
119624df6c6SStefano Ceccherini 
120624df6c6SStefano Ceccherini BRect
121624df6c6SStefano Ceccherini BPrivateScreen::Frame()
122624df6c6SStefano Ceccherini {
12339ffb980SStefano Ceccherini 	// If something goes wrong, we just return this rectangle.
12439ffb980SStefano Ceccherini 	BRect rect(0, 0, 0, 0);
125624df6c6SStefano Ceccherini 	display_mode mode;
12634c39bf0SStefano Ceccherini 	if (GetMode(B_CURRENT_WORKSPACE, &mode) == B_OK)
12739ffb980SStefano Ceccherini 		rect.Set(0, 0, (float)mode.virtual_width - 1, (float)mode.virtual_height - 1);
12839ffb980SStefano Ceccherini 
12939ffb980SStefano Ceccherini 	return rect;
130624df6c6SStefano Ceccherini }
131624df6c6SStefano Ceccherini 
132624df6c6SStefano Ceccherini 
133624df6c6SStefano Ceccherini screen_id
134624df6c6SStefano Ceccherini BPrivateScreen::ID()
135624df6c6SStefano Ceccherini {
13639ffb980SStefano Ceccherini 	// TODO: Change this if we start supporting multiple screens
137624df6c6SStefano Ceccherini 	return B_MAIN_SCREEN_ID;
138624df6c6SStefano Ceccherini }
139624df6c6SStefano Ceccherini 
140624df6c6SStefano Ceccherini 
141624df6c6SStefano Ceccherini status_t
142624df6c6SStefano Ceccherini BPrivateScreen::WaitForRetrace(bigtime_t timeout)
143624df6c6SStefano Ceccherini {
144624df6c6SStefano Ceccherini 	// Get the retrace semaphore if it's the first time
145624df6c6SStefano Ceccherini 	// we are called. Cache the value then.
146624df6c6SStefano Ceccherini 	status_t status;
14710c5dab8SStefano Ceccherini 	if (fRetraceSem < 0)
148624df6c6SStefano Ceccherini 		fRetraceSem = RetraceSemaphore();
149624df6c6SStefano Ceccherini 
150624df6c6SStefano Ceccherini 	do {
151624df6c6SStefano Ceccherini 		status = acquire_sem_etc(fRetraceSem, 1, B_RELATIVE_TIMEOUT, timeout);
152624df6c6SStefano Ceccherini 	} while (status == B_INTERRUPTED);
153624df6c6SStefano Ceccherini 
154624df6c6SStefano Ceccherini 	return status;
155624df6c6SStefano Ceccherini }
156624df6c6SStefano Ceccherini 
157624df6c6SStefano Ceccherini 
158624df6c6SStefano Ceccherini uint8
159624df6c6SStefano Ceccherini BPrivateScreen::IndexForColor(uint8 red, uint8 green, uint8 blue, uint8 alpha)
160624df6c6SStefano Ceccherini {
161624df6c6SStefano Ceccherini 	// Looks like this check is necessary
162624df6c6SStefano Ceccherini 	if (red == B_TRANSPARENT_COLOR.red && green == B_TRANSPARENT_COLOR.green &&
163624df6c6SStefano Ceccherini 		blue == B_TRANSPARENT_COLOR.blue && alpha == B_TRANSPARENT_COLOR.alpha)
164624df6c6SStefano Ceccherini 		return B_TRANSPARENT_8_BIT;
165624df6c6SStefano Ceccherini 
1662e6a5805SStephan Aßmus 	uint16 index = ((blue & 0xf8) << 7) | ((green & 0xf8) << 2) | (red >> 3);
167624df6c6SStefano Ceccherini 	if (fColorMap)
1682ed35bc8SStefano Ceccherini 		return fColorMap->index_map[index];
169624df6c6SStefano Ceccherini 
170624df6c6SStefano Ceccherini 	return 0;
171624df6c6SStefano Ceccherini }
172624df6c6SStefano Ceccherini 
173624df6c6SStefano Ceccherini 
174624df6c6SStefano Ceccherini rgb_color
175624df6c6SStefano Ceccherini BPrivateScreen::ColorForIndex(const uint8 index)
176624df6c6SStefano Ceccherini {
177624df6c6SStefano Ceccherini 	if (fColorMap)
178624df6c6SStefano Ceccherini 		return fColorMap->color_list[index];
179624df6c6SStefano Ceccherini 
180624df6c6SStefano Ceccherini 	return rgb_color();
181624df6c6SStefano Ceccherini }
182624df6c6SStefano Ceccherini 
183624df6c6SStefano Ceccherini 
184624df6c6SStefano Ceccherini uint8
185624df6c6SStefano Ceccherini BPrivateScreen::InvertIndex(uint8 index)
186624df6c6SStefano Ceccherini {
187624df6c6SStefano Ceccherini 	if (fColorMap)
188624df6c6SStefano Ceccherini 		return fColorMap->inversion_map[index];
189624df6c6SStefano Ceccherini 
190624df6c6SStefano Ceccherini 	return 0;
191624df6c6SStefano Ceccherini }
192624df6c6SStefano Ceccherini 
193624df6c6SStefano Ceccherini 
194624df6c6SStefano Ceccherini const color_map *
195624df6c6SStefano Ceccherini BPrivateScreen::ColorMap()
196624df6c6SStefano Ceccherini {
197624df6c6SStefano Ceccherini 	return fColorMap;
198624df6c6SStefano Ceccherini }
199624df6c6SStefano Ceccherini 
200624df6c6SStefano Ceccherini 
201624df6c6SStefano Ceccherini status_t
202*466871ccSAxel Dörfler BPrivateScreen::GetBitmap(BBitmap **_bitmap, bool drawCursor, BRect *bounds)
203624df6c6SStefano Ceccherini {
204*466871ccSAxel Dörfler 	if (_bitmap == NULL)
20516046321SStefano Ceccherini 		return B_BAD_VALUE;
20616046321SStefano Ceccherini 
207*466871ccSAxel Dörfler 	BBitmap* bitmap = new (std::nothrow) BBitmap(Frame(), ColorSpace());
208*466871ccSAxel Dörfler 	if (bitmap == NULL)
209*466871ccSAxel Dörfler 		return B_NO_MEMORY;
210*466871ccSAxel Dörfler 
211*466871ccSAxel Dörfler 	status_t status = bitmap->InitCheck();
212*466871ccSAxel Dörfler 	if (status == B_OK)
213*466871ccSAxel Dörfler 		status = ReadBitmap(bitmap, drawCursor, bounds);
214*466871ccSAxel Dörfler 	if (status != B_OK) {
215*466871ccSAxel Dörfler 		delete bitmap;
216*466871ccSAxel Dörfler 		return status;
217*466871ccSAxel Dörfler 	}
218*466871ccSAxel Dörfler 
219*466871ccSAxel Dörfler 	*_bitmap = bitmap;
220*466871ccSAxel Dörfler 	return B_OK;
221624df6c6SStefano Ceccherini }
222624df6c6SStefano Ceccherini 
223624df6c6SStefano Ceccherini 
224624df6c6SStefano Ceccherini status_t
225624df6c6SStefano Ceccherini BPrivateScreen::ReadBitmap(BBitmap *bitmap, bool drawCursor, BRect *bound)
226624df6c6SStefano Ceccherini {
22716046321SStefano Ceccherini 	if (bitmap == NULL)
22816046321SStefano Ceccherini 		return B_BAD_VALUE;
22916046321SStefano Ceccherini 
23016046321SStefano Ceccherini 	BRect rect;
23116046321SStefano Ceccherini 	if (bound != NULL)
23216046321SStefano Ceccherini 		rect = *bound;
23316046321SStefano Ceccherini 	else
23416046321SStefano Ceccherini 		rect = Frame();
23516046321SStefano Ceccherini 
23616046321SStefano Ceccherini 	BPrivate::AppServerLink link;
23716046321SStefano Ceccherini 	link.StartMessage(AS_READ_BITMAP);
23816046321SStefano Ceccherini 	link.Attach<int32>(bitmap->get_server_token());
23916046321SStefano Ceccherini 	link.Attach<bool>(drawCursor);
24016046321SStefano Ceccherini 	link.Attach<BRect>(rect);
24116046321SStefano Ceccherini 
24216046321SStefano Ceccherini 	int32 code;
24316046321SStefano Ceccherini 	if (link.FlushWithReply(code) < B_OK || code != SERVER_TRUE)
244624df6c6SStefano Ceccherini 		return B_ERROR;
24516046321SStefano Ceccherini 
24616046321SStefano Ceccherini 	return B_OK;
247624df6c6SStefano Ceccherini }
248624df6c6SStefano Ceccherini 
249624df6c6SStefano Ceccherini 
250624df6c6SStefano Ceccherini rgb_color
25139ffb980SStefano Ceccherini BPrivateScreen::DesktopColor(uint32 workspace)
252624df6c6SStefano Ceccherini {
2533ba7d6f3SAxel Dörfler 	rgb_color color = { 51, 102, 152, 255 };
254dd10337fSAxel Dörfler 	BPrivate::AppServerLink link;
2553ba7d6f3SAxel Dörfler 
2563ba7d6f3SAxel Dörfler 	link.StartMessage(AS_GET_DESKTOP_COLOR);
2573f319b33SMichael Lotz 	link.Attach<uint32>(workspace);
2583ba7d6f3SAxel Dörfler 
2593ba7d6f3SAxel Dörfler 	int32 code;
260dd10337fSAxel Dörfler 	if (link.FlushWithReply(code) == B_OK
2613ba7d6f3SAxel Dörfler 		&& code == SERVER_TRUE)
2623ba7d6f3SAxel Dörfler 		link.Read<rgb_color>(&color);
2633ba7d6f3SAxel Dörfler 
26439ffb980SStefano Ceccherini 	return color;
265624df6c6SStefano Ceccherini }
266624df6c6SStefano Ceccherini 
267624df6c6SStefano Ceccherini 
268624df6c6SStefano Ceccherini void
26939ffb980SStefano Ceccherini BPrivateScreen::SetDesktopColor(rgb_color color, uint32 workspace, bool makeDefault)
270624df6c6SStefano Ceccherini {
271dd10337fSAxel Dörfler 	BPrivate::AppServerLink link;
2723ba7d6f3SAxel Dörfler 
2733ba7d6f3SAxel Dörfler 	link.StartMessage(AS_SET_DESKTOP_COLOR);
27439ffb980SStefano Ceccherini 	link.Attach<rgb_color>(color);
27539ffb980SStefano Ceccherini 	link.Attach<int32>(workspace);
27639ffb980SStefano Ceccherini 	link.Attach<bool>(makeDefault);
27739ffb980SStefano Ceccherini 	link.Flush();
278624df6c6SStefano Ceccherini }
279624df6c6SStefano Ceccherini 
280624df6c6SStefano Ceccherini 
281624df6c6SStefano Ceccherini status_t
282c6418981SStefano Ceccherini BPrivateScreen::ProposeMode(display_mode *target,
283c6418981SStefano Ceccherini 				const display_mode *low, const display_mode *high)
284624df6c6SStefano Ceccherini {
285c6418981SStefano Ceccherini 	// We can't return B_BAD_VALUE here, because it's used to indicate
286c6418981SStefano Ceccherini 	// that the mode returned is supported, but it doesn't fall
287c6418981SStefano Ceccherini 	// within the limit (see ProposeMode() documentation)
288c6418981SStefano Ceccherini 	if (target == NULL || low == NULL || high == NULL)
289624df6c6SStefano Ceccherini 		return B_ERROR;
290c6418981SStefano Ceccherini 
291c6418981SStefano Ceccherini 	BPrivate::AppServerLink link;
292c6418981SStefano Ceccherini 	link.StartMessage(AS_PROPOSE_MODE);
293c6418981SStefano Ceccherini 	link.Attach<screen_id>(ID());
294583f6c3eSStefano Ceccherini 	link.Attach<display_mode>(*target);
295583f6c3eSStefano Ceccherini 	link.Attach<display_mode>(*low);
296583f6c3eSStefano Ceccherini 	link.Attach<display_mode>(*high);
297583f6c3eSStefano Ceccherini 
298c6418981SStefano Ceccherini 	int32 reply;
299c6418981SStefano Ceccherini 	status_t status = B_ERROR;
300c6418981SStefano Ceccherini 	if (link.FlushWithReply(reply) == B_OK && reply == SERVER_TRUE) {
301c6418981SStefano Ceccherini 		link.Read<display_mode>(target);
302c6418981SStefano Ceccherini 		// The status is important here. See documentation
303c6418981SStefano Ceccherini 		link.Read<status_t>(&status);
304c6418981SStefano Ceccherini 	}
305c6418981SStefano Ceccherini 
306c6418981SStefano Ceccherini 	return status;
307624df6c6SStefano Ceccherini }
308624df6c6SStefano Ceccherini 
309624df6c6SStefano Ceccherini 
310624df6c6SStefano Ceccherini status_t
31110c5dab8SStefano Ceccherini BPrivateScreen::GetModeList(display_mode **modeList, uint32 *count)
312624df6c6SStefano Ceccherini {
31310c5dab8SStefano Ceccherini 	if (modeList == NULL || count == NULL)
31410c5dab8SStefano Ceccherini 		return B_BAD_VALUE;
31510c5dab8SStefano Ceccherini 
31610c5dab8SStefano Ceccherini 	status_t status = B_ERROR;
31710c5dab8SStefano Ceccherini 	BPrivate::AppServerLink link;
31810c5dab8SStefano Ceccherini 	link.StartMessage(AS_GET_MODE_LIST);
31910c5dab8SStefano Ceccherini 	link.Attach<screen_id>(ID());
32010c5dab8SStefano Ceccherini 	int32 reply;
32110c5dab8SStefano Ceccherini 	if (link.FlushWithReply(reply) == B_OK && reply == SERVER_TRUE) {
32210c5dab8SStefano Ceccherini 		link.Read<uint32>(count);
32310c5dab8SStefano Ceccherini 		int32 size = *count * sizeof(display_mode);
32410c5dab8SStefano Ceccherini 		*modeList = (display_mode *)malloc(size);
32510c5dab8SStefano Ceccherini 		link.Read(*modeList, size);
32610c5dab8SStefano Ceccherini 		// TODO: get status from app_server
32710c5dab8SStefano Ceccherini 		status = B_OK;
32810c5dab8SStefano Ceccherini 	}
32910c5dab8SStefano Ceccherini 
33010c5dab8SStefano Ceccherini 	return status;
331624df6c6SStefano Ceccherini }
332624df6c6SStefano Ceccherini 
333624df6c6SStefano Ceccherini 
334624df6c6SStefano Ceccherini status_t
335624df6c6SStefano Ceccherini BPrivateScreen::GetMode(uint32 workspace, display_mode *mode)
336624df6c6SStefano Ceccherini {
337314a1024SStefano Ceccherini 	if (mode == NULL)
338314a1024SStefano Ceccherini 		return B_BAD_VALUE;
339314a1024SStefano Ceccherini 
340dd10337fSAxel Dörfler 	BPrivate::AppServerLink link;
34134c39bf0SStefano Ceccherini 	link.StartMessage(AS_SCREEN_GET_MODE);
34234c39bf0SStefano Ceccherini 	link.Attach<screen_id>(ID());
34339ffb980SStefano Ceccherini 	link.Attach<uint32>(workspace);
344fca6492fSStefano Ceccherini 
345dd10337fSAxel Dörfler 	int32 code;
346dd10337fSAxel Dörfler 	if (link.FlushWithReply(code) != B_OK
347dd10337fSAxel Dörfler 		|| code != SERVER_TRUE)
348fca6492fSStefano Ceccherini 		return B_ERROR;
34939ffb980SStefano Ceccherini 
35034c39bf0SStefano Ceccherini 	display_mode currentMode;
35134c39bf0SStefano Ceccherini 	link.Read<display_mode>(&currentMode);
35234c39bf0SStefano Ceccherini 
35334c39bf0SStefano Ceccherini 	status_t status = B_ERROR;
35434c39bf0SStefano Ceccherini 	link.Read<status_t>(&status);
35539ffb980SStefano Ceccherini 	if (status == B_OK && mode)
35639ffb980SStefano Ceccherini 		*mode = currentMode;
35734c39bf0SStefano Ceccherini 
35839ffb980SStefano Ceccherini 	return status;
359624df6c6SStefano Ceccherini }
360624df6c6SStefano Ceccherini 
361624df6c6SStefano Ceccherini 
362624df6c6SStefano Ceccherini status_t
363624df6c6SStefano Ceccherini BPrivateScreen::SetMode(uint32 workspace, display_mode *mode, bool makeDefault)
364624df6c6SStefano Ceccherini {
365314a1024SStefano Ceccherini 	if (mode == NULL)
366314a1024SStefano Ceccherini 		return B_BAD_VALUE;
367314a1024SStefano Ceccherini 
368dd10337fSAxel Dörfler 	BPrivate::AppServerLink link;
369314a1024SStefano Ceccherini 	link.StartMessage(AS_SCREEN_SET_MODE);
370314a1024SStefano Ceccherini 	link.Attach<screen_id>(ID());
37139ffb980SStefano Ceccherini 	link.Attach<uint32>(workspace);
37239ffb980SStefano Ceccherini 	link.Attach<display_mode>(*mode);
37339ffb980SStefano Ceccherini 	link.Attach<bool>(makeDefault);
374314a1024SStefano Ceccherini 
375314a1024SStefano Ceccherini 	status_t status = B_ERROR;
376dd10337fSAxel Dörfler 	int32 code;
377dd10337fSAxel Dörfler 	if (link.FlushWithReply(code) == B_OK && code == SERVER_TRUE)
378314a1024SStefano Ceccherini 		link.Read<status_t>(&status);
379314a1024SStefano Ceccherini 
38039ffb980SStefano Ceccherini 	return status;
381624df6c6SStefano Ceccherini }
382624df6c6SStefano Ceccherini 
383624df6c6SStefano Ceccherini 
384624df6c6SStefano Ceccherini status_t
385624df6c6SStefano Ceccherini BPrivateScreen::GetDeviceInfo(accelerant_device_info *info)
386624df6c6SStefano Ceccherini {
387c6418981SStefano Ceccherini 	if (info == NULL)
388c6418981SStefano Ceccherini 		return B_BAD_VALUE;
389c6418981SStefano Ceccherini 
390c6418981SStefano Ceccherini 	BPrivate::AppServerLink link;
391c6418981SStefano Ceccherini 	link.StartMessage(AS_GET_ACCELERANT_INFO);
392c6418981SStefano Ceccherini 	link.Attach<screen_id>(ID());
393c6418981SStefano Ceccherini 	int32 code;
394c6418981SStefano Ceccherini 	if (link.FlushWithReply(code) == B_OK && code == SERVER_TRUE) {
395c6418981SStefano Ceccherini 		link.Read<accelerant_device_info>(info);
396c6418981SStefano Ceccherini 		return B_OK;
397c6418981SStefano Ceccherini 	}
398c6418981SStefano Ceccherini 
399624df6c6SStefano Ceccherini 	return B_ERROR;
400624df6c6SStefano Ceccherini }
401624df6c6SStefano Ceccherini 
402624df6c6SStefano Ceccherini 
403624df6c6SStefano Ceccherini status_t
404624df6c6SStefano Ceccherini BPrivateScreen::GetPixelClockLimits(display_mode *mode, uint32 *low, uint32 *high)
405624df6c6SStefano Ceccherini {
40675de27f8SStefano Ceccherini 	if (mode == NULL || low == NULL || high == NULL)
40775de27f8SStefano Ceccherini 		return B_BAD_VALUE;
40875de27f8SStefano Ceccherini 
40975de27f8SStefano Ceccherini 	BPrivate::AppServerLink link;
41075de27f8SStefano Ceccherini 	link.StartMessage(AS_GET_PIXEL_CLOCK_LIMITS);
41175de27f8SStefano Ceccherini 	link.Attach<screen_id>(ID());
41275de27f8SStefano Ceccherini 	link.Attach<display_mode>(*mode);
41375de27f8SStefano Ceccherini 
41475de27f8SStefano Ceccherini 	int32 code;
41575de27f8SStefano Ceccherini 	if (link.FlushWithReply(code) == B_OK && code == SERVER_TRUE) {
41675de27f8SStefano Ceccherini 		link.Read<uint32>(low);
41775de27f8SStefano Ceccherini 		link.Read<uint32>(high);
41875de27f8SStefano Ceccherini 
41975de27f8SStefano Ceccherini 		return B_OK;
42075de27f8SStefano Ceccherini 	}
42175de27f8SStefano Ceccherini 
422624df6c6SStefano Ceccherini 	return B_ERROR;
423624df6c6SStefano Ceccherini }
424624df6c6SStefano Ceccherini 
425624df6c6SStefano Ceccherini 
426624df6c6SStefano Ceccherini status_t
427624df6c6SStefano Ceccherini BPrivateScreen::GetTimingConstraints(display_timing_constraints *dtc)
428624df6c6SStefano Ceccherini {
42955b222b0SStefano Ceccherini 	if (dtc == NULL)
43055b222b0SStefano Ceccherini 		return B_BAD_VALUE;
43155b222b0SStefano Ceccherini 
43275de27f8SStefano Ceccherini 	BPrivate::AppServerLink link;
43375de27f8SStefano Ceccherini 	link.StartMessage(AS_GET_TIMING_CONSTRAINTS);
43475de27f8SStefano Ceccherini 	link.Attach<screen_id>(ID());
43575de27f8SStefano Ceccherini 
43675de27f8SStefano Ceccherini 	int32 code;
43775de27f8SStefano Ceccherini 	if (link.FlushWithReply(code) == B_OK && code == SERVER_TRUE) {
43875de27f8SStefano Ceccherini 		link.Read<display_timing_constraints>(dtc);
43975de27f8SStefano Ceccherini 		return B_OK;
44075de27f8SStefano Ceccherini 	}
44175de27f8SStefano Ceccherini 
442624df6c6SStefano Ceccherini 	return B_ERROR;
443624df6c6SStefano Ceccherini }
444624df6c6SStefano Ceccherini 
445624df6c6SStefano Ceccherini 
446624df6c6SStefano Ceccherini status_t
447624df6c6SStefano Ceccherini BPrivateScreen::SetDPMS(uint32 dpmsState)
448624df6c6SStefano Ceccherini {
449dd10337fSAxel Dörfler 	BPrivate::AppServerLink link;
45055b222b0SStefano Ceccherini 	link.StartMessage(AS_SET_DPMS);
45139ffb980SStefano Ceccherini 	link.Attach<screen_id>(ID());
45239ffb980SStefano Ceccherini 	link.Attach<uint32>(dpmsState);
45355b222b0SStefano Ceccherini 	int32 reply;
45455b222b0SStefano Ceccherini 	if (link.FlushWithReply(reply) == B_OK && reply == SERVER_TRUE)
45555b222b0SStefano Ceccherini 		return B_OK;
45655b222b0SStefano Ceccherini 
45755b222b0SStefano Ceccherini 	return B_ERROR;
458624df6c6SStefano Ceccherini }
459624df6c6SStefano Ceccherini 
460624df6c6SStefano Ceccherini 
461624df6c6SStefano Ceccherini uint32
462624df6c6SStefano Ceccherini BPrivateScreen::DPMSState()
463624df6c6SStefano Ceccherini {
46439ffb980SStefano Ceccherini 	uint32 state = 0;
46555b222b0SStefano Ceccherini 
466dd10337fSAxel Dörfler 	BPrivate::AppServerLink link;
46755b222b0SStefano Ceccherini 	link.StartMessage(AS_GET_DPMS_STATE);
46839ffb980SStefano Ceccherini 	link.Attach<screen_id>(ID());
46955b222b0SStefano Ceccherini 	int32 reply;
47055b222b0SStefano Ceccherini 	if (link.FlushWithReply(reply) == B_OK && reply == SERVER_TRUE)
47155b222b0SStefano Ceccherini 		link.Read<uint32>(&state);
47255b222b0SStefano Ceccherini 
47339ffb980SStefano Ceccherini 	return state;
474624df6c6SStefano Ceccherini }
475624df6c6SStefano Ceccherini 
476624df6c6SStefano Ceccherini 
477624df6c6SStefano Ceccherini uint32
478624df6c6SStefano Ceccherini BPrivateScreen::DPMSCapabilites()
479624df6c6SStefano Ceccherini {
48039ffb980SStefano Ceccherini 	uint32 capabilities = 0;
48155b222b0SStefano Ceccherini 
482dd10337fSAxel Dörfler 	BPrivate::AppServerLink link;
48355b222b0SStefano Ceccherini 	link.StartMessage(AS_GET_DPMS_CAPABILITIES);
48439ffb980SStefano Ceccherini 	link.Attach<screen_id>(ID());
48555b222b0SStefano Ceccherini 	int32 reply;
48655b222b0SStefano Ceccherini 	if (link.FlushWithReply(reply) == B_OK && reply == SERVER_TRUE)
48755b222b0SStefano Ceccherini 		link.Read<uint32>(&capabilities);
48855b222b0SStefano Ceccherini 
48939ffb980SStefano Ceccherini 	return capabilities;
490624df6c6SStefano Ceccherini }
491624df6c6SStefano Ceccherini 
492624df6c6SStefano Ceccherini 
493624df6c6SStefano Ceccherini void *
494624df6c6SStefano Ceccherini BPrivateScreen::BaseAddress()
495624df6c6SStefano Ceccherini {
496624df6c6SStefano Ceccherini 	screen_desc desc;
497624df6c6SStefano Ceccherini 	if (get_screen_desc(&desc) == B_OK)
498624df6c6SStefano Ceccherini 		return desc.base_address;
499624df6c6SStefano Ceccherini 
500624df6c6SStefano Ceccherini 	return NULL;
501624df6c6SStefano Ceccherini }
502624df6c6SStefano Ceccherini 
503624df6c6SStefano Ceccherini 
504624df6c6SStefano Ceccherini uint32
505624df6c6SStefano Ceccherini BPrivateScreen::BytesPerRow()
506624df6c6SStefano Ceccherini {
507624df6c6SStefano Ceccherini 	screen_desc desc;
508624df6c6SStefano Ceccherini 	if (get_screen_desc(&desc) == B_OK)
509624df6c6SStefano Ceccherini 		return desc.bytes_per_row;
510624df6c6SStefano Ceccherini 	return 0;
511624df6c6SStefano Ceccherini }
512624df6c6SStefano Ceccherini 
513624df6c6SStefano Ceccherini 
514624df6c6SStefano Ceccherini status_t
515624df6c6SStefano Ceccherini BPrivateScreen::get_screen_desc(screen_desc *desc)
516624df6c6SStefano Ceccherini {
51739ffb980SStefano Ceccherini 	status_t status = B_ERROR;
51839ffb980SStefano Ceccherini 	/*
519dd10337fSAxel Dörfler 	BPrivate::AppServerLink link;
52039ffb980SStefano Ceccherini 	PortMessage reply;
52139ffb980SStefano Ceccherini 	link.SetOpCode(AS_GET_SCREEN_DESC);
52239ffb980SStefano Ceccherini 	link.Attach<screen_id>(ID());
52339ffb980SStefano Ceccherini 	link.FlushWithReply(&reply);
52439ffb980SStefano Ceccherini 	reply.Read<screen_desc>(*desc);
52539ffb980SStefano Ceccherini 	reply.Read<status_t>(&status);
52639ffb980SStefano Ceccherini 	*/
52739ffb980SStefano Ceccherini 	return status;
528624df6c6SStefano Ceccherini }
529624df6c6SStefano Ceccherini 
530624df6c6SStefano Ceccherini 
53175de27f8SStefano Ceccherini // private methods
53275de27f8SStefano Ceccherini sem_id
53375de27f8SStefano Ceccherini BPrivateScreen::RetraceSemaphore()
53475de27f8SStefano Ceccherini {
53575de27f8SStefano Ceccherini 	sem_id id = B_BAD_SEM_ID;
53675de27f8SStefano Ceccherini 
53775de27f8SStefano Ceccherini 	BPrivate::AppServerLink link;
53875de27f8SStefano Ceccherini 	link.StartMessage(AS_GET_RETRACE_SEMAPHORE);
53975de27f8SStefano Ceccherini 	link.Attach<screen_id>(ID());
54075de27f8SStefano Ceccherini 	int32 reply;
54175de27f8SStefano Ceccherini 	if (link.FlushWithReply(reply) == B_OK
54275de27f8SStefano Ceccherini 		&& reply == SERVER_TRUE)
54375de27f8SStefano Ceccherini 		link.Read<sem_id>(&id);
54475de27f8SStefano Ceccherini 
54575de27f8SStefano Ceccherini 	return id;
54675de27f8SStefano Ceccherini }
54775de27f8SStefano Ceccherini 
54875de27f8SStefano Ceccherini 
549624df6c6SStefano Ceccherini BPrivateScreen::BPrivateScreen()
550624df6c6SStefano Ceccherini 	:
551624df6c6SStefano Ceccherini 	fColorMap(NULL),
552624df6c6SStefano Ceccherini 	fRetraceSem(-1),
553624df6c6SStefano Ceccherini 	fOwnsColorMap(false)
554624df6c6SStefano Ceccherini {
5557475dcdfSStefano Ceccherini 	// TODO: BeOS R5 here gets the colormap pointer
5567475dcdfSStefano Ceccherini 	// (with BApplication::ro_offset_to_ptr() ?)
5577475dcdfSStefano Ceccherini 	// which is contained in a shared area created by the server.
558dd10337fSAxel Dörfler 	BPrivate::AppServerLink link;
5597475dcdfSStefano Ceccherini 	link.StartMessage(AS_SCREEN_GET_COLORMAP);
5607475dcdfSStefano Ceccherini 	link.Attach<screen_id>(ID());
561dd10337fSAxel Dörfler 
5627475dcdfSStefano Ceccherini 	int32 reply;
563dd10337fSAxel Dörfler 	if (link.FlushWithReply(reply) == B_OK && reply == SERVER_TRUE) {
5647475dcdfSStefano Ceccherini 		fColorMap = (color_map *)malloc(sizeof(color_map));
5657475dcdfSStefano Ceccherini 		fOwnsColorMap = true;
5662ed35bc8SStefano Ceccherini 		link.Read<color_map>(fColorMap);
5677475dcdfSStefano Ceccherini 	}
568624df6c6SStefano Ceccherini }
569624df6c6SStefano Ceccherini 
570624df6c6SStefano Ceccherini 
571624df6c6SStefano Ceccherini BPrivateScreen::~BPrivateScreen()
572624df6c6SStefano Ceccherini {
573624df6c6SStefano Ceccherini 	if (fOwnsColorMap)
574624df6c6SStefano Ceccherini 		free(fColorMap);
575624df6c6SStefano Ceccherini }
576