xref: /haiku/src/kits/interface/PrivateScreen.cpp (revision 55b222b0b02bcc53c7301f8e3200553f046bc4e5)
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 //------------------------------------------------------------------------------
278eae8b05SStefano Ceccherini #include <Locker.h>
28624df6c6SStefano Ceccherini #include <Window.h>
29314a1024SStefano Ceccherini 
30bbc3515bSAxel Dörfler #include <stdlib.h>
31624df6c6SStefano Ceccherini 
3234c39bf0SStefano Ceccherini #include "AppServerLink.h"
33624df6c6SStefano Ceccherini #include "PrivateScreen.h"
3434c39bf0SStefano Ceccherini #include "ServerProtocol.h"
3539ffb980SStefano Ceccherini 
36624df6c6SStefano Ceccherini 
37624df6c6SStefano Ceccherini // TODO: We should define this somewhere else
38624df6c6SStefano Ceccherini // We could find how R5 defines this, though it's not strictly necessary
3939ffb980SStefano Ceccherini // AFAIK, R5 here keeps also the screen width, height, colorspace, and some other things
4039ffb980SStefano Ceccherini // (it's 48 bytes big)
41624df6c6SStefano Ceccherini struct screen_desc {
42624df6c6SStefano Ceccherini 	void *base_address;
43624df6c6SStefano Ceccherini 	uint32 bytes_per_row;
44624df6c6SStefano Ceccherini };
45624df6c6SStefano Ceccherini 
46624df6c6SStefano Ceccherini 
478eae8b05SStefano Ceccherini static BPrivateScreen *sScreen;
488eae8b05SStefano Ceccherini 
498eae8b05SStefano Ceccherini // used to synchronize creation/deletion of the sScreen object
508eae8b05SStefano Ceccherini static BLocker sScreenLock("screen lock");
51624df6c6SStefano Ceccherini 
52624df6c6SStefano Ceccherini 
53ca8ed922SStefano Ceccherini using namespace BPrivate;
54ca8ed922SStefano Ceccherini 
55624df6c6SStefano Ceccherini BPrivateScreen *
56624df6c6SStefano Ceccherini BPrivateScreen::CheckOut(BWindow *win)
57624df6c6SStefano Ceccherini {
588eae8b05SStefano Ceccherini 	sScreenLock.Lock();
598eae8b05SStefano Ceccherini 
60e93cd650SStefano Ceccherini 	if (sScreen == NULL) {
6139ffb980SStefano Ceccherini 		// TODO: If we start supporting multiple monitors, we
6239ffb980SStefano Ceccherini 		// should return the right screen for the passed BWindow
638eae8b05SStefano Ceccherini 		sScreen = new BPrivateScreen();
648eae8b05SStefano Ceccherini 	}
658eae8b05SStefano Ceccherini 
668eae8b05SStefano Ceccherini 	sScreenLock.Unlock();
678eae8b05SStefano Ceccherini 
688eae8b05SStefano Ceccherini 	return sScreen;
69624df6c6SStefano Ceccherini }
70624df6c6SStefano Ceccherini 
71624df6c6SStefano Ceccherini 
72624df6c6SStefano Ceccherini BPrivateScreen *
73624df6c6SStefano Ceccherini BPrivateScreen::CheckOut(screen_id id)
74624df6c6SStefano Ceccherini {
758eae8b05SStefano Ceccherini 	sScreenLock.Lock();
768eae8b05SStefano Ceccherini 
77e93cd650SStefano Ceccherini 	if (sScreen == NULL) {
7839ffb980SStefano Ceccherini 		// TODO: If we start supporting multiple monitors, we
7939ffb980SStefano Ceccherini 		// should return the right object for the given screen_id
808eae8b05SStefano Ceccherini 		sScreen = new BPrivateScreen();
818eae8b05SStefano Ceccherini 	}
828eae8b05SStefano Ceccherini 
838eae8b05SStefano Ceccherini 	sScreenLock.Unlock();
848eae8b05SStefano Ceccherini 
858eae8b05SStefano Ceccherini 	return sScreen;
86624df6c6SStefano Ceccherini }
87624df6c6SStefano Ceccherini 
88624df6c6SStefano Ceccherini 
89624df6c6SStefano Ceccherini void
90624df6c6SStefano Ceccherini BPrivateScreen::Return(BPrivateScreen *screen)
91624df6c6SStefano Ceccherini {
92e93cd650SStefano Ceccherini 	// Never delete the sScreen object.
93e93cd650SStefano Ceccherini 	// system_colors() expects the colormap to be
94e93cd650SStefano Ceccherini 	// permanently stored within libbe.
95624df6c6SStefano Ceccherini }
96624df6c6SStefano Ceccherini 
97624df6c6SStefano Ceccherini 
98624df6c6SStefano Ceccherini status_t
99624df6c6SStefano Ceccherini BPrivateScreen::SetToNext()
100624df6c6SStefano Ceccherini {
101624df6c6SStefano Ceccherini 	// This function always returns B_ERROR
102624df6c6SStefano Ceccherini 	return B_ERROR;
103624df6c6SStefano Ceccherini }
104624df6c6SStefano Ceccherini 
105624df6c6SStefano Ceccherini 
106624df6c6SStefano Ceccherini color_space
107624df6c6SStefano Ceccherini BPrivateScreen::ColorSpace()
108624df6c6SStefano Ceccherini {
109624df6c6SStefano Ceccherini 	display_mode mode;
1101f41d635SStefano Ceccherini 	if (GetMode(B_CURRENT_WORKSPACE, &mode) == B_OK)
111624df6c6SStefano Ceccherini 		return (color_space)mode.space;
112624df6c6SStefano Ceccherini 
113624df6c6SStefano Ceccherini 	return B_NO_COLOR_SPACE;
114624df6c6SStefano Ceccherini }
115624df6c6SStefano Ceccherini 
116624df6c6SStefano Ceccherini 
117624df6c6SStefano Ceccherini BRect
118624df6c6SStefano Ceccherini BPrivateScreen::Frame()
119624df6c6SStefano Ceccherini {
12039ffb980SStefano Ceccherini 	// If something goes wrong, we just return this rectangle.
12139ffb980SStefano Ceccherini 	BRect rect(0, 0, 0, 0);
122624df6c6SStefano Ceccherini 	display_mode mode;
12334c39bf0SStefano Ceccherini 	if (GetMode(B_CURRENT_WORKSPACE, &mode) == B_OK)
12439ffb980SStefano Ceccherini 		rect.Set(0, 0, (float)mode.virtual_width - 1, (float)mode.virtual_height - 1);
12539ffb980SStefano Ceccherini 
12639ffb980SStefano Ceccherini 	return rect;
127624df6c6SStefano Ceccherini }
128624df6c6SStefano Ceccherini 
129624df6c6SStefano Ceccherini 
130624df6c6SStefano Ceccherini screen_id
131624df6c6SStefano Ceccherini BPrivateScreen::ID()
132624df6c6SStefano Ceccherini {
13339ffb980SStefano Ceccherini 	// TODO: Change this if we start supporting multiple screens
134624df6c6SStefano Ceccherini 	return B_MAIN_SCREEN_ID;
135624df6c6SStefano Ceccherini }
136624df6c6SStefano Ceccherini 
137624df6c6SStefano Ceccherini 
138624df6c6SStefano Ceccherini status_t
139624df6c6SStefano Ceccherini BPrivateScreen::WaitForRetrace(bigtime_t timeout)
140624df6c6SStefano Ceccherini {
141624df6c6SStefano Ceccherini 	// Get the retrace semaphore if it's the first time
142624df6c6SStefano Ceccherini 	// we are called. Cache the value then.
143624df6c6SStefano Ceccherini 	status_t status;
14410c5dab8SStefano Ceccherini 	if (fRetraceSem < 0)
145624df6c6SStefano Ceccherini 		fRetraceSem = RetraceSemaphore();
146624df6c6SStefano Ceccherini 
147624df6c6SStefano Ceccherini 	do {
148624df6c6SStefano Ceccherini 		status = acquire_sem_etc(fRetraceSem, 1, B_RELATIVE_TIMEOUT, timeout);
149624df6c6SStefano Ceccherini 	} while (status == B_INTERRUPTED);
150624df6c6SStefano Ceccherini 
151624df6c6SStefano Ceccherini 	return status;
152624df6c6SStefano Ceccherini }
153624df6c6SStefano Ceccherini 
154624df6c6SStefano Ceccherini 
155624df6c6SStefano Ceccherini uint8
156624df6c6SStefano Ceccherini BPrivateScreen::IndexForColor(uint8 red, uint8 green, uint8 blue, uint8 alpha)
157624df6c6SStefano Ceccherini {
158624df6c6SStefano Ceccherini 	// Looks like this check is necessary
159624df6c6SStefano Ceccherini 	if (red == B_TRANSPARENT_COLOR.red && green == B_TRANSPARENT_COLOR.green &&
160624df6c6SStefano Ceccherini 		blue == B_TRANSPARENT_COLOR.blue && alpha == B_TRANSPARENT_COLOR.alpha)
161624df6c6SStefano Ceccherini 		return B_TRANSPARENT_8_BIT;
162624df6c6SStefano Ceccherini 
1632ed35bc8SStefano Ceccherini 	uint8 index = ((red & 0xf8) << 7) | ((green & 0xf8) << 2) | (blue >> 3);
164624df6c6SStefano Ceccherini 	if (fColorMap)
1652ed35bc8SStefano Ceccherini 		return fColorMap->index_map[index];
166624df6c6SStefano Ceccherini 
167624df6c6SStefano Ceccherini 	return 0;
168624df6c6SStefano Ceccherini }
169624df6c6SStefano Ceccherini 
170624df6c6SStefano Ceccherini 
171624df6c6SStefano Ceccherini rgb_color
172624df6c6SStefano Ceccherini BPrivateScreen::ColorForIndex(const uint8 index)
173624df6c6SStefano Ceccherini {
174624df6c6SStefano Ceccherini 	if (fColorMap)
175624df6c6SStefano Ceccherini 		return fColorMap->color_list[index];
176624df6c6SStefano Ceccherini 
177624df6c6SStefano Ceccherini 	return rgb_color();
178624df6c6SStefano Ceccherini }
179624df6c6SStefano Ceccherini 
180624df6c6SStefano Ceccherini 
181624df6c6SStefano Ceccherini uint8
182624df6c6SStefano Ceccherini BPrivateScreen::InvertIndex(uint8 index)
183624df6c6SStefano Ceccherini {
184624df6c6SStefano Ceccherini 	if (fColorMap)
185624df6c6SStefano Ceccherini 		return fColorMap->inversion_map[index];
186624df6c6SStefano Ceccherini 
187624df6c6SStefano Ceccherini 	return 0;
188624df6c6SStefano Ceccherini }
189624df6c6SStefano Ceccherini 
190624df6c6SStefano Ceccherini 
191624df6c6SStefano Ceccherini const color_map *
192624df6c6SStefano Ceccherini BPrivateScreen::ColorMap()
193624df6c6SStefano Ceccherini {
194624df6c6SStefano Ceccherini 	return fColorMap;
195624df6c6SStefano Ceccherini }
196624df6c6SStefano Ceccherini 
197624df6c6SStefano Ceccherini 
198624df6c6SStefano Ceccherini status_t
199624df6c6SStefano Ceccherini BPrivateScreen::GetBitmap(BBitmap **bitmap, bool drawCursor, BRect *bound)
200624df6c6SStefano Ceccherini {
201624df6c6SStefano Ceccherini 	// TODO: Implement
202624df6c6SStefano Ceccherini 	return B_ERROR;
203624df6c6SStefano Ceccherini }
204624df6c6SStefano Ceccherini 
205624df6c6SStefano Ceccherini 
206624df6c6SStefano Ceccherini status_t
207624df6c6SStefano Ceccherini BPrivateScreen::ReadBitmap(BBitmap *bitmap, bool drawCursor, BRect *bound)
208624df6c6SStefano Ceccherini {
209624df6c6SStefano Ceccherini 	// TODO: Implement
210624df6c6SStefano Ceccherini 	return B_ERROR;
211624df6c6SStefano Ceccherini }
212624df6c6SStefano Ceccherini 
213624df6c6SStefano Ceccherini 
214624df6c6SStefano Ceccherini rgb_color
21539ffb980SStefano Ceccherini BPrivateScreen::DesktopColor(uint32 workspace)
216624df6c6SStefano Ceccherini {
2173ba7d6f3SAxel Dörfler 	rgb_color color = { 51, 102, 152, 255 };
218dd10337fSAxel Dörfler 	BPrivate::AppServerLink link;
2193ba7d6f3SAxel Dörfler 
2203ba7d6f3SAxel Dörfler 	link.StartMessage(AS_GET_DESKTOP_COLOR);
22139ffb980SStefano Ceccherini 	link.Attach<int32>(workspace);
2223ba7d6f3SAxel Dörfler 
2233ba7d6f3SAxel Dörfler 	int32 code;
224dd10337fSAxel Dörfler 	if (link.FlushWithReply(code) == B_OK
2253ba7d6f3SAxel Dörfler 		&& code == SERVER_TRUE)
2263ba7d6f3SAxel Dörfler 		link.Read<rgb_color>(&color);
2273ba7d6f3SAxel Dörfler 
22839ffb980SStefano Ceccherini 	return color;
229624df6c6SStefano Ceccherini }
230624df6c6SStefano Ceccherini 
231624df6c6SStefano Ceccherini 
232624df6c6SStefano Ceccherini void
23339ffb980SStefano Ceccherini BPrivateScreen::SetDesktopColor(rgb_color color, uint32 workspace, bool makeDefault)
234624df6c6SStefano Ceccherini {
235dd10337fSAxel Dörfler 	BPrivate::AppServerLink link;
2363ba7d6f3SAxel Dörfler 
2373ba7d6f3SAxel Dörfler 	link.StartMessage(AS_SET_DESKTOP_COLOR);
23839ffb980SStefano Ceccherini 	link.Attach<rgb_color>(color);
23939ffb980SStefano Ceccherini 	link.Attach<int32>(workspace);
24039ffb980SStefano Ceccherini 	link.Attach<bool>(makeDefault);
24139ffb980SStefano Ceccherini 	link.Flush();
242624df6c6SStefano Ceccherini }
243624df6c6SStefano Ceccherini 
244624df6c6SStefano Ceccherini 
245624df6c6SStefano Ceccherini status_t
246c6418981SStefano Ceccherini BPrivateScreen::ProposeMode(display_mode *target,
247c6418981SStefano Ceccherini 				const display_mode *low, const display_mode *high)
248624df6c6SStefano Ceccherini {
249c6418981SStefano Ceccherini 	// We can't return B_BAD_VALUE here, because it's used to indicate
250c6418981SStefano Ceccherini 	// that the mode returned is supported, but it doesn't fall
251c6418981SStefano Ceccherini 	// within the limit (see ProposeMode() documentation)
252c6418981SStefano Ceccherini 	if (target == NULL || low == NULL || high == NULL)
253624df6c6SStefano Ceccherini 		return B_ERROR;
254c6418981SStefano Ceccherini 
255c6418981SStefano Ceccherini 	BPrivate::AppServerLink link;
256c6418981SStefano Ceccherini 	link.StartMessage(AS_PROPOSE_MODE);
257c6418981SStefano Ceccherini 	link.Attach<screen_id>(ID());
258583f6c3eSStefano Ceccherini 	link.Attach<display_mode>(*target);
259583f6c3eSStefano Ceccherini 	link.Attach<display_mode>(*low);
260583f6c3eSStefano Ceccherini 	link.Attach<display_mode>(*high);
261583f6c3eSStefano Ceccherini 
262c6418981SStefano Ceccherini 	int32 reply;
263c6418981SStefano Ceccherini 	status_t status = B_ERROR;
264c6418981SStefano Ceccherini 	if (link.FlushWithReply(reply) == B_OK && reply == SERVER_TRUE) {
265c6418981SStefano Ceccherini 		link.Read<display_mode>(target);
266c6418981SStefano Ceccherini 		// The status is important here. See documentation
267c6418981SStefano Ceccherini 		link.Read<status_t>(&status);
268c6418981SStefano Ceccherini 	}
269c6418981SStefano Ceccherini 
270c6418981SStefano Ceccherini 	return status;
271624df6c6SStefano Ceccherini }
272624df6c6SStefano Ceccherini 
273624df6c6SStefano Ceccherini 
274624df6c6SStefano Ceccherini status_t
27510c5dab8SStefano Ceccherini BPrivateScreen::GetModeList(display_mode **modeList, uint32 *count)
276624df6c6SStefano Ceccherini {
27710c5dab8SStefano Ceccherini 	if (modeList == NULL || count == NULL)
27810c5dab8SStefano Ceccherini 		return B_BAD_VALUE;
27910c5dab8SStefano Ceccherini 
28010c5dab8SStefano Ceccherini 	status_t status = B_ERROR;
28110c5dab8SStefano Ceccherini 	BPrivate::AppServerLink link;
28210c5dab8SStefano Ceccherini 	link.StartMessage(AS_GET_MODE_LIST);
28310c5dab8SStefano Ceccherini 	link.Attach<screen_id>(ID());
28410c5dab8SStefano Ceccherini 	int32 reply;
28510c5dab8SStefano Ceccherini 	if (link.FlushWithReply(reply) == B_OK && reply == SERVER_TRUE) {
28610c5dab8SStefano Ceccherini 		link.Read<uint32>(count);
28710c5dab8SStefano Ceccherini 		int32 size = *count * sizeof(display_mode);
28810c5dab8SStefano Ceccherini 		*modeList = (display_mode *)malloc(size);
28910c5dab8SStefano Ceccherini 		link.Read(*modeList, size);
29010c5dab8SStefano Ceccherini 		// TODO: get status from app_server
29110c5dab8SStefano Ceccherini 		status = B_OK;
29210c5dab8SStefano Ceccherini 	}
29310c5dab8SStefano Ceccherini 
29410c5dab8SStefano Ceccherini 	return status;
295624df6c6SStefano Ceccherini }
296624df6c6SStefano Ceccherini 
297624df6c6SStefano Ceccherini 
298624df6c6SStefano Ceccherini status_t
299624df6c6SStefano Ceccherini BPrivateScreen::GetMode(uint32 workspace, display_mode *mode)
300624df6c6SStefano Ceccherini {
301314a1024SStefano Ceccherini 	if (mode == NULL)
302314a1024SStefano Ceccherini 		return B_BAD_VALUE;
303314a1024SStefano Ceccherini 
304dd10337fSAxel Dörfler 	BPrivate::AppServerLink link;
30534c39bf0SStefano Ceccherini 	link.StartMessage(AS_SCREEN_GET_MODE);
30634c39bf0SStefano Ceccherini 	link.Attach<screen_id>(ID());
30739ffb980SStefano Ceccherini 	link.Attach<uint32>(workspace);
308fca6492fSStefano Ceccherini 
309dd10337fSAxel Dörfler 	int32 code;
310dd10337fSAxel Dörfler 	if (link.FlushWithReply(code) != B_OK
311dd10337fSAxel Dörfler 		|| code != SERVER_TRUE)
312fca6492fSStefano Ceccherini 		return B_ERROR;
31339ffb980SStefano Ceccherini 
31434c39bf0SStefano Ceccherini 	display_mode currentMode;
31534c39bf0SStefano Ceccherini 	link.Read<display_mode>(&currentMode);
31634c39bf0SStefano Ceccherini 
31734c39bf0SStefano Ceccherini 	status_t status = B_ERROR;
31834c39bf0SStefano Ceccherini 	link.Read<status_t>(&status);
31939ffb980SStefano Ceccherini 	if (status == B_OK && mode)
32039ffb980SStefano Ceccherini 		*mode = currentMode;
32134c39bf0SStefano Ceccherini 
32239ffb980SStefano Ceccherini 	return status;
323624df6c6SStefano Ceccherini }
324624df6c6SStefano Ceccherini 
325624df6c6SStefano Ceccherini 
326624df6c6SStefano Ceccherini status_t
327624df6c6SStefano Ceccherini BPrivateScreen::SetMode(uint32 workspace, display_mode *mode, bool makeDefault)
328624df6c6SStefano Ceccherini {
329314a1024SStefano Ceccherini 	if (mode == NULL)
330314a1024SStefano Ceccherini 		return B_BAD_VALUE;
331314a1024SStefano Ceccherini 
332dd10337fSAxel Dörfler 	BPrivate::AppServerLink link;
333314a1024SStefano Ceccherini 	link.StartMessage(AS_SCREEN_SET_MODE);
334314a1024SStefano Ceccherini 	link.Attach<screen_id>(ID());
33539ffb980SStefano Ceccherini 	link.Attach<uint32>(workspace);
33639ffb980SStefano Ceccherini 	link.Attach<display_mode>(*mode);
33739ffb980SStefano Ceccherini 	link.Attach<bool>(makeDefault);
338314a1024SStefano Ceccherini 
339314a1024SStefano Ceccherini 	status_t status = B_ERROR;
340dd10337fSAxel Dörfler 	int32 code;
341dd10337fSAxel Dörfler 	if (link.FlushWithReply(code) == B_OK && code == SERVER_TRUE)
342314a1024SStefano Ceccherini 		link.Read<status_t>(&status);
343314a1024SStefano Ceccherini 
34439ffb980SStefano Ceccherini 	return status;
345624df6c6SStefano Ceccherini }
346624df6c6SStefano Ceccherini 
347624df6c6SStefano Ceccherini 
348624df6c6SStefano Ceccherini status_t
349624df6c6SStefano Ceccherini BPrivateScreen::GetDeviceInfo(accelerant_device_info *info)
350624df6c6SStefano Ceccherini {
351c6418981SStefano Ceccherini 	if (info == NULL)
352c6418981SStefano Ceccherini 		return B_BAD_VALUE;
353c6418981SStefano Ceccherini 
354c6418981SStefano Ceccherini 	BPrivate::AppServerLink link;
355c6418981SStefano Ceccherini 	link.StartMessage(AS_GET_ACCELERANT_INFO);
356c6418981SStefano Ceccherini 	link.Attach<screen_id>(ID());
357c6418981SStefano Ceccherini 	int32 code;
358c6418981SStefano Ceccherini 	if (link.FlushWithReply(code) == B_OK && code == SERVER_TRUE) {
359c6418981SStefano Ceccherini 		link.Read<accelerant_device_info>(info);
360c6418981SStefano Ceccherini 		return B_OK;
361c6418981SStefano Ceccherini 	}
362c6418981SStefano Ceccherini 
363624df6c6SStefano Ceccherini 	return B_ERROR;
364624df6c6SStefano Ceccherini }
365624df6c6SStefano Ceccherini 
366624df6c6SStefano Ceccherini 
367624df6c6SStefano Ceccherini status_t
368624df6c6SStefano Ceccherini BPrivateScreen::GetPixelClockLimits(display_mode *mode, uint32 *low, uint32 *high)
369624df6c6SStefano Ceccherini {
37075de27f8SStefano Ceccherini 	if (mode == NULL || low == NULL || high == NULL)
37175de27f8SStefano Ceccherini 		return B_BAD_VALUE;
37275de27f8SStefano Ceccherini 
37375de27f8SStefano Ceccherini 	BPrivate::AppServerLink link;
37475de27f8SStefano Ceccherini 	link.StartMessage(AS_GET_PIXEL_CLOCK_LIMITS);
37575de27f8SStefano Ceccherini 	link.Attach<screen_id>(ID());
37675de27f8SStefano Ceccherini 	link.Attach<display_mode>(*mode);
37775de27f8SStefano Ceccherini 
37875de27f8SStefano Ceccherini 	int32 code;
37975de27f8SStefano Ceccherini 	if (link.FlushWithReply(code) == B_OK && code == SERVER_TRUE) {
38075de27f8SStefano Ceccherini 		link.Read<uint32>(low);
38175de27f8SStefano Ceccherini 		link.Read<uint32>(high);
38275de27f8SStefano Ceccherini 
38375de27f8SStefano Ceccherini 		return B_OK;
38475de27f8SStefano Ceccherini 	}
38575de27f8SStefano Ceccherini 
386624df6c6SStefano Ceccherini 	return B_ERROR;
387624df6c6SStefano Ceccherini }
388624df6c6SStefano Ceccherini 
389624df6c6SStefano Ceccherini 
390624df6c6SStefano Ceccherini status_t
391624df6c6SStefano Ceccherini BPrivateScreen::GetTimingConstraints(display_timing_constraints *dtc)
392624df6c6SStefano Ceccherini {
393*55b222b0SStefano Ceccherini 	if (dtc == NULL)
394*55b222b0SStefano Ceccherini 		return B_BAD_VALUE;
395*55b222b0SStefano Ceccherini 
39675de27f8SStefano Ceccherini 	BPrivate::AppServerLink link;
39775de27f8SStefano Ceccherini 	link.StartMessage(AS_GET_TIMING_CONSTRAINTS);
39875de27f8SStefano Ceccherini 	link.Attach<screen_id>(ID());
39975de27f8SStefano Ceccherini 
40075de27f8SStefano Ceccherini 	int32 code;
40175de27f8SStefano Ceccherini 	if (link.FlushWithReply(code) == B_OK && code == SERVER_TRUE) {
40275de27f8SStefano Ceccherini 		link.Read<display_timing_constraints>(dtc);
40375de27f8SStefano Ceccherini 		return B_OK;
40475de27f8SStefano Ceccherini 	}
40575de27f8SStefano Ceccherini 
406624df6c6SStefano Ceccherini 	return B_ERROR;
407624df6c6SStefano Ceccherini }
408624df6c6SStefano Ceccherini 
409624df6c6SStefano Ceccherini 
410624df6c6SStefano Ceccherini status_t
411624df6c6SStefano Ceccherini BPrivateScreen::SetDPMS(uint32 dpmsState)
412624df6c6SStefano Ceccherini {
413dd10337fSAxel Dörfler 	BPrivate::AppServerLink link;
414*55b222b0SStefano Ceccherini 	link.StartMessage(AS_SET_DPMS);
41539ffb980SStefano Ceccherini 	link.Attach<screen_id>(ID());
41639ffb980SStefano Ceccherini 	link.Attach<uint32>(dpmsState);
417*55b222b0SStefano Ceccherini 	int32 reply;
418*55b222b0SStefano Ceccherini 	if (link.FlushWithReply(reply) == B_OK && reply == SERVER_TRUE)
419*55b222b0SStefano Ceccherini 		return B_OK;
420*55b222b0SStefano Ceccherini 
421*55b222b0SStefano Ceccherini 	return B_ERROR;
422624df6c6SStefano Ceccherini }
423624df6c6SStefano Ceccherini 
424624df6c6SStefano Ceccherini 
425624df6c6SStefano Ceccherini uint32
426624df6c6SStefano Ceccherini BPrivateScreen::DPMSState()
427624df6c6SStefano Ceccherini {
42839ffb980SStefano Ceccherini 	uint32 state = 0;
429*55b222b0SStefano Ceccherini 
430dd10337fSAxel Dörfler 	BPrivate::AppServerLink link;
431*55b222b0SStefano Ceccherini 	link.StartMessage(AS_GET_DPMS_STATE);
43239ffb980SStefano Ceccherini 	link.Attach<screen_id>(ID());
433*55b222b0SStefano Ceccherini 	int32 reply;
434*55b222b0SStefano Ceccherini 	if (link.FlushWithReply(reply) == B_OK && reply == SERVER_TRUE)
435*55b222b0SStefano Ceccherini 		link.Read<uint32>(&state);
436*55b222b0SStefano Ceccherini 
43739ffb980SStefano Ceccherini 	return state;
438624df6c6SStefano Ceccherini }
439624df6c6SStefano Ceccherini 
440624df6c6SStefano Ceccherini 
441624df6c6SStefano Ceccherini uint32
442624df6c6SStefano Ceccherini BPrivateScreen::DPMSCapabilites()
443624df6c6SStefano Ceccherini {
44439ffb980SStefano Ceccherini 	uint32 capabilities = 0;
445*55b222b0SStefano Ceccherini 
446dd10337fSAxel Dörfler 	BPrivate::AppServerLink link;
447*55b222b0SStefano Ceccherini 	link.StartMessage(AS_GET_DPMS_CAPABILITIES);
44839ffb980SStefano Ceccherini 	link.Attach<screen_id>(ID());
449*55b222b0SStefano Ceccherini 	int32 reply;
450*55b222b0SStefano Ceccherini 	if (link.FlushWithReply(reply) == B_OK && reply == SERVER_TRUE)
451*55b222b0SStefano Ceccherini 		link.Read<uint32>(&capabilities);
452*55b222b0SStefano Ceccherini 
45339ffb980SStefano Ceccherini 	return capabilities;
454624df6c6SStefano Ceccherini }
455624df6c6SStefano Ceccherini 
456624df6c6SStefano Ceccherini 
457624df6c6SStefano Ceccherini void *
458624df6c6SStefano Ceccherini BPrivateScreen::BaseAddress()
459624df6c6SStefano Ceccherini {
460624df6c6SStefano Ceccherini 	screen_desc desc;
461624df6c6SStefano Ceccherini 	if (get_screen_desc(&desc) == B_OK)
462624df6c6SStefano Ceccherini 		return desc.base_address;
463624df6c6SStefano Ceccherini 
464624df6c6SStefano Ceccherini 	return NULL;
465624df6c6SStefano Ceccherini }
466624df6c6SStefano Ceccherini 
467624df6c6SStefano Ceccherini 
468624df6c6SStefano Ceccherini uint32
469624df6c6SStefano Ceccherini BPrivateScreen::BytesPerRow()
470624df6c6SStefano Ceccherini {
471624df6c6SStefano Ceccherini 	screen_desc desc;
472624df6c6SStefano Ceccherini 	if (get_screen_desc(&desc) == B_OK)
473624df6c6SStefano Ceccherini 		return desc.bytes_per_row;
474624df6c6SStefano Ceccherini 	return 0;
475624df6c6SStefano Ceccherini }
476624df6c6SStefano Ceccherini 
477624df6c6SStefano Ceccherini 
478624df6c6SStefano Ceccherini status_t
479624df6c6SStefano Ceccherini BPrivateScreen::get_screen_desc(screen_desc *desc)
480624df6c6SStefano Ceccherini {
48139ffb980SStefano Ceccherini 	status_t status = B_ERROR;
48239ffb980SStefano Ceccherini 	/*
483dd10337fSAxel Dörfler 	BPrivate::AppServerLink link;
48439ffb980SStefano Ceccherini 	PortMessage reply;
48539ffb980SStefano Ceccherini 	link.SetOpCode(AS_GET_SCREEN_DESC);
48639ffb980SStefano Ceccherini 	link.Attach<screen_id>(ID());
48739ffb980SStefano Ceccherini 	link.FlushWithReply(&reply);
48839ffb980SStefano Ceccherini 	reply.Read<screen_desc>(*desc);
48939ffb980SStefano Ceccherini 	reply.Read<status_t>(&status);
49039ffb980SStefano Ceccherini 	*/
49139ffb980SStefano Ceccherini 	return status;
492624df6c6SStefano Ceccherini }
493624df6c6SStefano Ceccherini 
494624df6c6SStefano Ceccherini 
49575de27f8SStefano Ceccherini // private methods
49675de27f8SStefano Ceccherini sem_id
49775de27f8SStefano Ceccherini BPrivateScreen::RetraceSemaphore()
49875de27f8SStefano Ceccherini {
49975de27f8SStefano Ceccherini 	sem_id id = B_BAD_SEM_ID;
50075de27f8SStefano Ceccherini 
50175de27f8SStefano Ceccherini 	BPrivate::AppServerLink link;
50275de27f8SStefano Ceccherini 	link.StartMessage(AS_GET_RETRACE_SEMAPHORE);
50375de27f8SStefano Ceccherini 	link.Attach<screen_id>(ID());
50475de27f8SStefano Ceccherini 	int32 reply;
50575de27f8SStefano Ceccherini 	if (link.FlushWithReply(reply) == B_OK
50675de27f8SStefano Ceccherini 		&& reply == SERVER_TRUE)
50775de27f8SStefano Ceccherini 		link.Read<sem_id>(&id);
50875de27f8SStefano Ceccherini 
50975de27f8SStefano Ceccherini 	return id;
51075de27f8SStefano Ceccherini }
51175de27f8SStefano Ceccherini 
51275de27f8SStefano Ceccherini 
513624df6c6SStefano Ceccherini BPrivateScreen::BPrivateScreen()
514624df6c6SStefano Ceccherini 	:
515624df6c6SStefano Ceccherini 	fColorMap(NULL),
516624df6c6SStefano Ceccherini 	fRetraceSem(-1),
517624df6c6SStefano Ceccherini 	fOwnsColorMap(false)
518624df6c6SStefano Ceccherini {
5197475dcdfSStefano Ceccherini 	// TODO: BeOS R5 here gets the colormap pointer
5207475dcdfSStefano Ceccherini 	// (with BApplication::ro_offset_to_ptr() ?)
5217475dcdfSStefano Ceccherini 	// which is contained in a shared area created by the server.
522dd10337fSAxel Dörfler 	BPrivate::AppServerLink link;
5237475dcdfSStefano Ceccherini 	link.StartMessage(AS_SCREEN_GET_COLORMAP);
5247475dcdfSStefano Ceccherini 	link.Attach<screen_id>(ID());
525dd10337fSAxel Dörfler 
5267475dcdfSStefano Ceccherini 	int32 reply;
527dd10337fSAxel Dörfler 	if (link.FlushWithReply(reply) == B_OK && reply == SERVER_TRUE) {
5287475dcdfSStefano Ceccherini 		fColorMap = (color_map *)malloc(sizeof(color_map));
5297475dcdfSStefano Ceccherini 		fOwnsColorMap = true;
5302ed35bc8SStefano Ceccherini 		link.Read<color_map>(fColorMap);
5317475dcdfSStefano Ceccherini 	}
532624df6c6SStefano Ceccherini }
533624df6c6SStefano Ceccherini 
534624df6c6SStefano Ceccherini 
535624df6c6SStefano Ceccherini BPrivateScreen::~BPrivateScreen()
536624df6c6SStefano Ceccherini {
537624df6c6SStefano Ceccherini 	if (fOwnsColorMap)
538624df6c6SStefano Ceccherini 		free(fColorMap);
539624df6c6SStefano Ceccherini }
540