xref: /haiku/src/preferences/screen/ScreenWindow.cpp (revision 8b46ee25ac1409929f9a11efb254525e19b9b0bf)
1a10cf76eSAxel Dörfler /*
2e1c88201SJohn Scipione  * Copyright 2001-2013, Haiku, Inc.
3a10cf76eSAxel Dörfler  * Distributed under the terms of the MIT License.
4a10cf76eSAxel Dörfler  *
5a10cf76eSAxel Dörfler  * Authors:
6e1c88201SJohn Scipione  *		Stephan Aßmus, superstippi@gmx.de
7a10cf76eSAxel Dörfler  *		Andrew Bachmann
8e1c88201SJohn Scipione  *		Stefano Ceccherini, burton666@libero.it
9e1c88201SJohn Scipione  *		Alexandre Deckner, alex@zappotek.com
10e1c88201SJohn Scipione  *		Axel Dörfler, axeld@pinc-software.de
117e44de36SRene Gollent  *		Rene Gollent, rene@gollent.com
12a10cf76eSAxel Dörfler  *		Thomas Kurschel
13e1c88201SJohn Scipione  *		Rafael Romo
14e1c88201SJohn Scipione  *		John Scipione, jscipione@gmail.com
15a10cf76eSAxel Dörfler  */
16a10cf76eSAxel Dörfler 
17a10cf76eSAxel Dörfler 
18b21d610eSAxel Dörfler #include "ScreenWindow.h"
19b21d610eSAxel Dörfler 
20b21d610eSAxel Dörfler #include <stdio.h>
21b21d610eSAxel Dörfler #include <stdlib.h>
223aeed660SJérôme Duval #include <strings.h>
23b21d610eSAxel Dörfler 
24b21d610eSAxel Dörfler #include <Alert.h>
25b21d610eSAxel Dörfler #include <Application.h>
26b21d610eSAxel Dörfler #include <Box.h>
27b21d610eSAxel Dörfler #include <Button.h>
28c9e8f97aSAdrien Destugues #include <Catalog.h>
29e1c88201SJohn Scipione #include <ControlLook.h>
30b21d610eSAxel Dörfler #include <Directory.h>
31b21d610eSAxel Dörfler #include <File.h>
32b21d610eSAxel Dörfler #include <FindDirectory.h>
33b21d610eSAxel Dörfler #include <InterfaceDefs.h>
34b21d610eSAxel Dörfler #include <LayoutBuilder.h>
35b21d610eSAxel Dörfler #include <MenuBar.h>
36b21d610eSAxel Dörfler #include <MenuItem.h>
37b21d610eSAxel Dörfler #include <MenuField.h>
38b21d610eSAxel Dörfler #include <Messenger.h>
39b21d610eSAxel Dörfler #include <Path.h>
40b21d610eSAxel Dörfler #include <PopUpMenu.h>
41b21d610eSAxel Dörfler #include <Screen.h>
42e1c88201SJohn Scipione #include <SpaceLayoutItem.h>
43b21d610eSAxel Dörfler #include <String.h>
44b21d610eSAxel Dörfler #include <StringView.h>
45b21d610eSAxel Dörfler #include <Roster.h>
46b21d610eSAxel Dörfler #include <Window.h>
47b21d610eSAxel Dörfler 
48b21d610eSAxel Dörfler #include <InterfacePrivate.h>
49b21d610eSAxel Dörfler 
50a10cf76eSAxel Dörfler #include "AlertWindow.h"
51a10cf76eSAxel Dörfler #include "Constants.h"
52a10cf76eSAxel Dörfler #include "RefreshWindow.h"
53a10cf76eSAxel Dörfler #include "MonitorView.h"
54a10cf76eSAxel Dörfler #include "ScreenSettings.h"
55a10cf76eSAxel Dörfler #include "Utility.h"
56a10cf76eSAxel Dörfler 
57a10cf76eSAxel Dörfler /* Note, this headers defines a *private* interface to the Radeon accelerant.
58a10cf76eSAxel Dörfler  * It's a solution that works with the current BeOS interface that Haiku
59a10cf76eSAxel Dörfler  * adopted.
60a10cf76eSAxel Dörfler  * However, it's not a nice and clean solution. Don't use this header in any
61a10cf76eSAxel Dörfler  * application if you can avoid it. No other driver is using this, or should
62a10cf76eSAxel Dörfler  * be using this.
63a10cf76eSAxel Dörfler  * It will be replaced as soon as we introduce an updated accelerant interface
64a10cf76eSAxel Dörfler  * which may even happen before R1 hits the streets.
65a10cf76eSAxel Dörfler  */
66a10cf76eSAxel Dörfler #include "multimon.h"	// the usual: DANGER WILL, ROBINSON!
67a10cf76eSAxel Dörfler 
68a10cf76eSAxel Dörfler 
69546208a5SOliver Tappe #undef B_TRANSLATION_CONTEXT
70546208a5SOliver Tappe #define B_TRANSLATION_CONTEXT "Screen"
71c9e8f97aSAdrien Destugues 
72c9e8f97aSAdrien Destugues 
7375c92c56SRyan Leavengood const char* kBackgroundsSignature = "application/x-vnd.Haiku-Backgrounds";
74c5d80d47SAxel Dörfler 
75a10cf76eSAxel Dörfler // list of officially supported colour spaces
76a10cf76eSAxel Dörfler static const struct {
77a10cf76eSAxel Dörfler 	color_space	space;
78a10cf76eSAxel Dörfler 	int32		bits_per_pixel;
79a10cf76eSAxel Dörfler 	const char*	label;
80a10cf76eSAxel Dörfler } kColorSpaces[] = {
8126747978SAdrien Destugues 	{ B_CMAP8, 8, B_TRANSLATE("8 bits/pixel, 256 colors") },
82c9e8f97aSAdrien Destugues 	{ B_RGB15, 15, B_TRANSLATE("15 bits/pixel, 32768 colors") },
83c9e8f97aSAdrien Destugues 	{ B_RGB16, 16, B_TRANSLATE("16 bits/pixel, 65536 colors") },
84c9e8f97aSAdrien Destugues 	{ B_RGB24, 24, B_TRANSLATE("24 bits/pixel, 16 Million colors") },
85c9e8f97aSAdrien Destugues 	{ B_RGB32, 32, B_TRANSLATE("32 bits/pixel, 16 Million colors") }
86a10cf76eSAxel Dörfler };
87b21d610eSAxel Dörfler static const int32 kColorSpaceCount
88b21d610eSAxel Dörfler 	= sizeof(kColorSpaces) / sizeof(kColorSpaces[0]);
89a10cf76eSAxel Dörfler 
90a10cf76eSAxel Dörfler // list of standard refresh rates
91a796facfSAxel Dörfler static const int32 kRefreshRates[] = { 60, 70, 72, 75, 80, 85, 95, 100 };
92b21d610eSAxel Dörfler static const int32 kRefreshRateCount
93b21d610eSAxel Dörfler 	= sizeof(kRefreshRates) / sizeof(kRefreshRates[0]);
94a10cf76eSAxel Dörfler 
95a10cf76eSAxel Dörfler // list of combine modes
96a10cf76eSAxel Dörfler static const struct {
97a10cf76eSAxel Dörfler 	combine_mode	mode;
98a10cf76eSAxel Dörfler 	const char		*name;
99a10cf76eSAxel Dörfler } kCombineModes[] = {
100c9e8f97aSAdrien Destugues 	{ kCombineDisable, B_TRANSLATE("disable") },
101c9e8f97aSAdrien Destugues 	{ kCombineHorizontally, B_TRANSLATE("horizontally") },
102c9e8f97aSAdrien Destugues 	{ kCombineVertically, B_TRANSLATE("vertically") }
103a10cf76eSAxel Dörfler };
104b21d610eSAxel Dörfler static const int32 kCombineModeCount
105b21d610eSAxel Dörfler 	= sizeof(kCombineModes) / sizeof(kCombineModes[0]);
10629e8a73aSAxel Dörfler 
107a10cf76eSAxel Dörfler 
108a10cf76eSAxel Dörfler static BString
109a10cf76eSAxel Dörfler tv_standard_to_string(uint32 mode)
110a10cf76eSAxel Dörfler {
111a10cf76eSAxel Dörfler 	switch (mode) {
112a10cf76eSAxel Dörfler 		case 0:		return "disabled";
113a10cf76eSAxel Dörfler 		case 1:		return "NTSC";
114a10cf76eSAxel Dörfler 		case 2:		return "NTSC Japan";
115a10cf76eSAxel Dörfler 		case 3:		return "PAL BDGHI";
116a10cf76eSAxel Dörfler 		case 4:		return "PAL M";
117a10cf76eSAxel Dörfler 		case 5:		return "PAL N";
118a10cf76eSAxel Dörfler 		case 6:		return "SECAM";
119a10cf76eSAxel Dörfler 		case 101:	return "NTSC 443";
120a10cf76eSAxel Dörfler 		case 102:	return "PAL 60";
121a10cf76eSAxel Dörfler 		case 103:	return "PAL NC";
122a10cf76eSAxel Dörfler 		default:
123a10cf76eSAxel Dörfler 		{
124a10cf76eSAxel Dörfler 			BString name;
125a10cf76eSAxel Dörfler 			name << "??? (" << mode << ")";
126a10cf76eSAxel Dörfler 
127a10cf76eSAxel Dörfler 			return name;
128a10cf76eSAxel Dörfler 		}
129a10cf76eSAxel Dörfler 	}
130a10cf76eSAxel Dörfler }
131a10cf76eSAxel Dörfler 
132a10cf76eSAxel Dörfler 
133a10cf76eSAxel Dörfler static void
134a10cf76eSAxel Dörfler resolution_to_string(screen_mode& mode, BString &string)
135a10cf76eSAxel Dörfler {
136a10cf76eSAxel Dörfler 	string << mode.width << " x " << mode.height;
137a10cf76eSAxel Dörfler }
138a10cf76eSAxel Dörfler 
139a10cf76eSAxel Dörfler 
140a10cf76eSAxel Dörfler static void
141a10cf76eSAxel Dörfler refresh_rate_to_string(float refresh, BString &string,
142a10cf76eSAxel Dörfler 	bool appendUnit = true, bool alwaysWithFraction = false)
143a10cf76eSAxel Dörfler {
1448bf23e3cSAxel Dörfler 	snprintf(string.LockBuffer(32), 32, "%.*g", refresh >= 100.0 ? 4 : 3,
1458bf23e3cSAxel Dörfler 		refresh);
146a10cf76eSAxel Dörfler 	string.UnlockBuffer();
147a10cf76eSAxel Dörfler 
148a10cf76eSAxel Dörfler 	if (appendUnit)
149551c9f15SSiarzhuk Zharski 		string << " " << B_TRANSLATE("Hz");
150a10cf76eSAxel Dörfler }
151a10cf76eSAxel Dörfler 
152a10cf76eSAxel Dörfler 
15307184a9eSAxel Dörfler static const char*
15407184a9eSAxel Dörfler screen_errors(status_t status)
15507184a9eSAxel Dörfler {
15607184a9eSAxel Dörfler 	switch (status) {
15707184a9eSAxel Dörfler 		case B_ENTRY_NOT_FOUND:
158c9e8f97aSAdrien Destugues 			return B_TRANSLATE("Unknown mode");
15907184a9eSAxel Dörfler 		// TODO: add more?
16007184a9eSAxel Dörfler 
16107184a9eSAxel Dörfler 		default:
16207184a9eSAxel Dörfler 			return strerror(status);
16307184a9eSAxel Dörfler 	}
16407184a9eSAxel Dörfler }
16507184a9eSAxel Dörfler 
16629e8a73aSAxel Dörfler 
1673dfd20c0SStephan Aßmus //	#pragma mark -
1683dfd20c0SStephan Aßmus 
1693dfd20c0SStephan Aßmus 
1705a78744bSAxel Dörfler ScreenWindow::ScreenWindow(ScreenSettings* settings)
171b21d610eSAxel Dörfler 	:
172560ff447SJonas Sundström 	BWindow(settings->WindowFrame(), B_TRANSLATE_SYSTEM_NAME("Screen"),
173958e0ca5SJohn Scipione 		B_TITLED_WINDOW, B_NOT_RESIZABLE | B_NOT_ZOOMABLE
174958e0ca5SJohn Scipione 		| B_AUTO_UPDATE_SIZE_LIMITS, B_ALL_WORKSPACES),
1753f953a72SAxel Dörfler 	fIsVesa(false),
176199893c3SAxel Dörfler 	fBootWorkspaceApplied(false),
1777e44de36SRene Gollent 	fOtherRefresh(NULL),
178294a85aaSRene Gollent 	fScreenMode(this),
17961c5c89bSAxel Dörfler 	fUndoScreenMode(this),
180abc649b8SWaldemar Kornewald 	fModified(false)
181a10cf76eSAxel Dörfler {
182a10cf76eSAxel Dörfler 	BScreen screen(this);
183a10cf76eSAxel Dörfler 
18412580984SAxel Dörfler 	accelerant_device_info info;
185d1516993SAxel Dörfler 	if (screen.GetDeviceInfo(&info) == B_OK
186d1516993SAxel Dörfler 		&& !strcasecmp(info.chipset, "VESA"))
18712580984SAxel Dörfler 		fIsVesa = true;
18812580984SAxel Dörfler 
1895de171daSAxel Dörfler 	_UpdateOriginal();
1901fc4cb1fSAxel Dörfler 	_BuildSupportedColorSpaces();
191a10cf76eSAxel Dörfler 	fActive = fSelected = fOriginal;
192a10cf76eSAxel Dörfler 
1935a78744bSAxel Dörfler 	fSettings = settings;
1945a78744bSAxel Dörfler 
1955a78744bSAxel Dörfler 	// we need the "Current Workspace" first to get its height
1965a78744bSAxel Dörfler 
197c9e8f97aSAdrien Destugues 	BPopUpMenu *popUpMenu = new BPopUpMenu(B_TRANSLATE("Current workspace"),
198c9e8f97aSAdrien Destugues 		true, true);
199c9e8f97aSAdrien Destugues 	fAllWorkspacesItem = new BMenuItem(B_TRANSLATE("All workspaces"),
200d1516993SAxel Dörfler 		new BMessage(WORKSPACE_CHECK_MSG));
2015a78744bSAxel Dörfler 	popUpMenu->AddItem(fAllWorkspacesItem);
202c9e8f97aSAdrien Destugues 	BMenuItem *item = new BMenuItem(B_TRANSLATE("Current workspace"),
203d1516993SAxel Dörfler 		new BMessage(WORKSPACE_CHECK_MSG));
204b72c4836SAlexandre Deckner 
2055a78744bSAxel Dörfler 	popUpMenu->AddItem(item);
20627c43a2dSRene Gollent 	fAllWorkspacesItem->SetMarked(true);
2075a78744bSAxel Dörfler 
208b21d610eSAxel Dörfler 	BMenuField* workspaceMenuField = new BMenuField("WorkspaceMenu", NULL,
20910dfe897SAxel Dörfler 		popUpMenu);
2105a78744bSAxel Dörfler 	workspaceMenuField->ResizeToPreferred();
211a10cf76eSAxel Dörfler 
212a10cf76eSAxel Dörfler 	// box on the left with workspace count and monitor view
213a10cf76eSAxel Dörfler 
214b21d610eSAxel Dörfler 	BBox* screenBox = new BBox("screen box");
215e1c88201SJohn Scipione 	BGroupLayout* layout = new BGroupLayout(B_VERTICAL, B_USE_SMALL_SPACING);
216e1c88201SJohn Scipione 	layout->SetInsets(B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING,
217e1c88201SJohn Scipione 		B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING);
218b21d610eSAxel Dörfler 	screenBox->SetLayout(layout);
219a10cf76eSAxel Dörfler 
22012966d04SAxel Dörfler 	fMonitorInfo = new BStringView("monitor info", "");
221e1c88201SJohn Scipione 	fMonitorInfo->SetAlignment(B_ALIGN_CENTER);
22212966d04SAxel Dörfler 	screenBox->AddChild(fMonitorInfo);
22312966d04SAxel Dörfler 
224*8b46ee25SAdrien Destugues 	fDeviceInfo = new BStringView("monitor info", "");
225*8b46ee25SAdrien Destugues 	fDeviceInfo->SetAlignment(B_ALIGN_CENTER);
226*8b46ee25SAdrien Destugues 	screenBox->AddChild(fDeviceInfo);
227*8b46ee25SAdrien Destugues 
228c9e8f97aSAdrien Destugues 	fMonitorView = new MonitorView(BRect(0.0, 0.0, 80.0, 80.0),
229551c9f15SSiarzhuk Zharski 		"monitor", screen.Frame().IntegerWidth() + 1,
230c9e8f97aSAdrien Destugues 		screen.Frame().IntegerHeight() + 1);
231b21d610eSAxel Dörfler 	screenBox->AddChild(fMonitorView);
2325a78744bSAxel Dörfler 
233e1c88201SJohn Scipione 	BStringView* workspaces = new BStringView("workspaces",
234e1c88201SJohn Scipione 		B_TRANSLATE("Workspaces"));
235e1c88201SJohn Scipione 	workspaces->SetAlignment(B_ALIGN_CENTER);
236e1c88201SJohn Scipione 
237c9e8f97aSAdrien Destugues 	fColumnsControl = new BTextControl(B_TRANSLATE("Columns:"), "0",
238b21d610eSAxel Dörfler 		new BMessage(kMsgWorkspaceColumnsChanged));
239e1c88201SJohn Scipione 	fColumnsControl->SetAlignment(B_ALIGN_RIGHT, B_ALIGN_LEFT);
240c9e8f97aSAdrien Destugues 	fRowsControl = new BTextControl(B_TRANSLATE("Rows:"), "0",
241b21d610eSAxel Dörfler 		new BMessage(kMsgWorkspaceRowsChanged));
242e1c88201SJohn Scipione 	fRowsControl->SetAlignment(B_ALIGN_RIGHT, B_ALIGN_LEFT);
243b21d610eSAxel Dörfler 
244e1c88201SJohn Scipione 	float tiny = be_control_look->DefaultItemSpacing() / 4;
245e1c88201SJohn Scipione 	screenBox->AddChild(BLayoutBuilder::Group<>()
246e1c88201SJohn Scipione 		.AddGroup(B_VERTICAL, B_USE_SMALL_SPACING)
247e1c88201SJohn Scipione 			.Add(workspaces)
248e1c88201SJohn Scipione 			.AddGrid(0.0, tiny)
249e1c88201SJohn Scipione 				// columns
250e1c88201SJohn Scipione 				.Add(fColumnsControl->CreateLabelLayoutItem(), 0, 0)
251e1c88201SJohn Scipione 				.Add(BSpaceLayoutItem::CreateHorizontalStrut(
252e1c88201SJohn Scipione 					B_USE_SMALL_SPACING), 1, 0)
253e1c88201SJohn Scipione 				.Add(fColumnsControl->CreateTextViewLayoutItem(), 2, 0)
254e1c88201SJohn Scipione 				.Add(BSpaceLayoutItem::CreateHorizontalStrut(tiny), 3, 0)
255e1c88201SJohn Scipione 				.Add(_CreateColumnRowButton(true, false), 4, 0)
256e1c88201SJohn Scipione 				.Add(_CreateColumnRowButton(true, true), 5, 0)
257e1c88201SJohn Scipione 				// rows
258e1c88201SJohn Scipione 				.Add(fRowsControl->CreateLabelLayoutItem(), 0, 1)
259e1c88201SJohn Scipione 				.Add(BSpaceLayoutItem::CreateHorizontalStrut(
260e1c88201SJohn Scipione 					B_USE_SMALL_SPACING), 1, 1)
261e1c88201SJohn Scipione 				.Add(fRowsControl->CreateTextViewLayoutItem(), 2, 1)
262e1c88201SJohn Scipione 				.Add(BSpaceLayoutItem::CreateHorizontalStrut(tiny), 3, 1)
263e1c88201SJohn Scipione 				.Add(_CreateColumnRowButton(false, false), 4, 1)
264e1c88201SJohn Scipione 				.Add(_CreateColumnRowButton(false, true), 5, 1)
265b21d610eSAxel Dörfler 				.End()
26625fd5c7bSAlex Wilson 			.End()
26725fd5c7bSAlex Wilson 		.View());
268b21d610eSAxel Dörfler 
269b21d610eSAxel Dörfler 	fBackgroundsButton = new BButton("BackgroundsButton",
270c9e8f97aSAdrien Destugues 		B_TRANSLATE("Set background" B_UTF8_ELLIPSIS),
271b21d610eSAxel Dörfler 		new BMessage(BUTTON_LAUNCH_BACKGROUNDS_MSG));
272b21d610eSAxel Dörfler 	fBackgroundsButton->SetFontSize(be_plain_font->Size() * 0.9);
273b21d610eSAxel Dörfler 	screenBox->AddChild(fBackgroundsButton);
274a10cf76eSAxel Dörfler 
275a10cf76eSAxel Dörfler 	// box on the right with screen resolution, etc.
276a10cf76eSAxel Dörfler 
277b21d610eSAxel Dörfler 	BBox* controlsBox = new BBox("controls box");
278b21d610eSAxel Dörfler 	controlsBox->SetLabel(workspaceMenuField);
2796048f541SJohn Scipione 	BGroupView* outerControlsView = new BGroupView(B_VERTICAL);
2806048f541SJohn Scipione 	outerControlsView->GroupLayout()->SetInsets(B_USE_DEFAULT_SPACING,
2816048f541SJohn Scipione 		B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING);
282b21d610eSAxel Dörfler 	controlsBox->AddChild(outerControlsView);
283a10cf76eSAxel Dörfler 
284551c9f15SSiarzhuk Zharski 	fResolutionMenu = new BPopUpMenu("resolution", true, true);
285a10cf76eSAxel Dörfler 
28666ab1666SAxel Dörfler 	uint16 maxWidth = 0;
28766ab1666SAxel Dörfler 	uint16 maxHeight = 0;
28866ab1666SAxel Dörfler 	uint16 previousWidth = 0;
28966ab1666SAxel Dörfler 	uint16 previousHeight = 0;
290a10cf76eSAxel Dörfler 	for (int32 i = 0; i < fScreenMode.CountModes(); i++) {
291a10cf76eSAxel Dörfler 		screen_mode mode = fScreenMode.ModeAt(i);
292a10cf76eSAxel Dörfler 
293a10cf76eSAxel Dörfler 		if (mode.width == previousWidth && mode.height == previousHeight)
294a10cf76eSAxel Dörfler 			continue;
295a10cf76eSAxel Dörfler 
296a10cf76eSAxel Dörfler 		previousWidth = mode.width;
297a10cf76eSAxel Dörfler 		previousHeight = mode.height;
29866ab1666SAxel Dörfler 		if (maxWidth < mode.width)
29966ab1666SAxel Dörfler 			maxWidth = mode.width;
30066ab1666SAxel Dörfler 		if (maxHeight < mode.height)
30166ab1666SAxel Dörfler 			maxHeight = mode.height;
302a10cf76eSAxel Dörfler 
303a10cf76eSAxel Dörfler 		BMessage* message = new BMessage(POP_RESOLUTION_MSG);
304a10cf76eSAxel Dörfler 		message->AddInt32("width", mode.width);
305a10cf76eSAxel Dörfler 		message->AddInt32("height", mode.height);
306a10cf76eSAxel Dörfler 
307a10cf76eSAxel Dörfler 		BString name;
308a10cf76eSAxel Dörfler 		name << mode.width << " x " << mode.height;
309a10cf76eSAxel Dörfler 
310a10cf76eSAxel Dörfler 		fResolutionMenu->AddItem(new BMenuItem(name.String(), message));
311a10cf76eSAxel Dörfler 	}
312a10cf76eSAxel Dörfler 
31366ab1666SAxel Dörfler 	fMonitorView->SetMaxResolution(maxWidth, maxHeight);
31466ab1666SAxel Dörfler 
315c9e8f97aSAdrien Destugues 	fResolutionField = new BMenuField("ResolutionMenu",
31610dfe897SAxel Dörfler 		B_TRANSLATE("Resolution:"), fResolutionMenu);
3176048f541SJohn Scipione 	fResolutionField->SetAlignment(B_ALIGN_RIGHT);
318a10cf76eSAxel Dörfler 
319551c9f15SSiarzhuk Zharski 	fColorsMenu = new BPopUpMenu("colors", true, false);
320a10cf76eSAxel Dörfler 
321a10cf76eSAxel Dörfler 	for (int32 i = 0; i < kColorSpaceCount; i++) {
3221fc4cb1fSAxel Dörfler 		if ((fSupportedColorSpaces & (1 << i)) == 0)
3231fc4cb1fSAxel Dörfler 			continue;
3241fc4cb1fSAxel Dörfler 
325a10cf76eSAxel Dörfler 		BMessage* message = new BMessage(POP_COLORS_MSG);
326a10cf76eSAxel Dörfler 		message->AddInt32("bits_per_pixel", kColorSpaces[i].bits_per_pixel);
327a10cf76eSAxel Dörfler 		message->AddInt32("space", kColorSpaces[i].space);
328a10cf76eSAxel Dörfler 
3291fc4cb1fSAxel Dörfler 		BMenuItem* item = new BMenuItem(kColorSpaces[i].label, message);
3301fc4cb1fSAxel Dörfler 		if (kColorSpaces[i].space == screen.ColorSpace())
3311fc4cb1fSAxel Dörfler 			fUserSelectedColorSpace = item;
3321fc4cb1fSAxel Dörfler 
3331fc4cb1fSAxel Dörfler 		fColorsMenu->AddItem(item);
334a10cf76eSAxel Dörfler 	}
335a10cf76eSAxel Dörfler 
336c9e8f97aSAdrien Destugues 	fColorsField = new BMenuField("ColorsMenu", B_TRANSLATE("Colors:"),
33710dfe897SAxel Dörfler 		fColorsMenu);
3386048f541SJohn Scipione 	fColorsField->SetAlignment(B_ALIGN_RIGHT);
339a10cf76eSAxel Dörfler 
340551c9f15SSiarzhuk Zharski 	fRefreshMenu = new BPopUpMenu("refresh rate", true, true);
341a10cf76eSAxel Dörfler 
34229e8a73aSAxel Dörfler 	float min, max;
343ec495b30SRene Gollent 	if (fScreenMode.GetRefreshLimits(fActive, min, max) != B_OK) {
344ec495b30SRene Gollent 		// if we couldn't obtain the refresh limits, reset to the default
345ec495b30SRene Gollent 		// range. Constraints from detected monitors will fine-tune this
346ec495b30SRene Gollent 		// later.
347ec495b30SRene Gollent 		min = kRefreshRates[0];
348ec495b30SRene Gollent 		max = kRefreshRates[kRefreshRateCount - 1];
349ec495b30SRene Gollent 	}
350ec495b30SRene Gollent 
351ec495b30SRene Gollent 	if (min == max) {
35229e8a73aSAxel Dörfler 		// This is a special case for drivers that only support a single
35329e8a73aSAxel Dörfler 		// frequency, like the VESA driver
35429e8a73aSAxel Dörfler 		BString name;
3557e44de36SRene Gollent 		refresh_rate_to_string(min, name);
356cf076964SRene Gollent 		BMessage *message = new BMessage(POP_REFRESH_MSG);
357cf076964SRene Gollent 		message->AddFloat("refresh", min);
358cf076964SRene Gollent 		BMenuItem *item = new BMenuItem(name.String(), message);
3590efb8b66SJerome Duval 		fRefreshMenu->AddItem(item);
36029e8a73aSAxel Dörfler 		item->SetEnabled(false);
36129e8a73aSAxel Dörfler 	} else {
36270a2b1b5SAxel Dörfler 		monitor_info info;
36370a2b1b5SAxel Dörfler 		if (fScreenMode.GetMonitorInfo(info) == B_OK) {
36470a2b1b5SAxel Dörfler 			min = max_c(info.min_vertical_frequency, min);
36570a2b1b5SAxel Dörfler 			max = min_c(info.max_vertical_frequency, max);
36670a2b1b5SAxel Dörfler 		}
36770a2b1b5SAxel Dörfler 
368a10cf76eSAxel Dörfler 		for (int32 i = 0; i < kRefreshRateCount; ++i) {
36970a2b1b5SAxel Dörfler 			if (kRefreshRates[i] < min || kRefreshRates[i] > max)
37070a2b1b5SAxel Dörfler 				continue;
37170a2b1b5SAxel Dörfler 
372a10cf76eSAxel Dörfler 			BString name;
373551c9f15SSiarzhuk Zharski 			name << kRefreshRates[i] << " " << B_TRANSLATE("Hz");
374a10cf76eSAxel Dörfler 
3750efb8b66SJerome Duval 			BMessage *message = new BMessage(POP_REFRESH_MSG);
376a10cf76eSAxel Dörfler 			message->AddFloat("refresh", kRefreshRates[i]);
377a10cf76eSAxel Dörfler 
378a10cf76eSAxel Dörfler 			fRefreshMenu->AddItem(new BMenuItem(name.String(), message));
379a10cf76eSAxel Dörfler 		}
380a10cf76eSAxel Dörfler 
381c9e8f97aSAdrien Destugues 		fOtherRefresh = new BMenuItem(B_TRANSLATE("Other" B_UTF8_ELLIPSIS),
3820efb8b66SJerome Duval 			new BMessage(POP_OTHER_REFRESH_MSG));
383a10cf76eSAxel Dörfler 		fRefreshMenu->AddItem(fOtherRefresh);
38429e8a73aSAxel Dörfler 	}
385a10cf76eSAxel Dörfler 
386c9e8f97aSAdrien Destugues 	fRefreshField = new BMenuField("RefreshMenu", B_TRANSLATE("Refresh rate:"),
38710dfe897SAxel Dörfler 		fRefreshMenu);
3886048f541SJohn Scipione 	fRefreshField->SetAlignment(B_ALIGN_RIGHT);
389b21d610eSAxel Dörfler 
39012580984SAxel Dörfler 	if (_IsVesa())
39112580984SAxel Dörfler 		fRefreshField->Hide();
392a10cf76eSAxel Dörfler 
393a10cf76eSAxel Dörfler 	// enlarged area for multi-monitor settings
394a10cf76eSAxel Dörfler 	{
395a10cf76eSAxel Dörfler 		bool dummy;
396a10cf76eSAxel Dörfler 		uint32 dummy32;
397a10cf76eSAxel Dörfler 		bool multiMonSupport;
398a10cf76eSAxel Dörfler 		bool useLaptopPanelSupport;
399a10cf76eSAxel Dörfler 		bool tvStandardSupport;
400a10cf76eSAxel Dörfler 
401a10cf76eSAxel Dörfler 		multiMonSupport = TestMultiMonSupport(&screen) == B_OK;
402a10cf76eSAxel Dörfler 		useLaptopPanelSupport = GetUseLaptopPanel(&screen, &dummy) == B_OK;
403a10cf76eSAxel Dörfler 		tvStandardSupport = GetTVStandard(&screen, &dummy32) == B_OK;
404a10cf76eSAxel Dörfler 
405a10cf76eSAxel Dörfler 		// even if there is no support, we still create all controls
406a10cf76eSAxel Dörfler 		// to make sure we don't access NULL pointers later on
407a10cf76eSAxel Dörfler 
408551c9f15SSiarzhuk Zharski 		fCombineMenu = new BPopUpMenu("CombineDisplays",
409c9e8f97aSAdrien Destugues 			true, true);
410a10cf76eSAxel Dörfler 
411a10cf76eSAxel Dörfler 		for (int32 i = 0; i < kCombineModeCount; i++) {
4120efb8b66SJerome Duval 			BMessage *message = new BMessage(POP_COMBINE_DISPLAYS_MSG);
413a10cf76eSAxel Dörfler 			message->AddInt32("mode", kCombineModes[i].mode);
414a10cf76eSAxel Dörfler 
415d1516993SAxel Dörfler 			fCombineMenu->AddItem(new BMenuItem(kCombineModes[i].name,
416d1516993SAxel Dörfler 				message));
417a10cf76eSAxel Dörfler 		}
418a10cf76eSAxel Dörfler 
419b21d610eSAxel Dörfler 		fCombineField = new BMenuField("CombineMenu",
42010dfe897SAxel Dörfler 			B_TRANSLATE("Combine displays:"), fCombineMenu);
4216048f541SJohn Scipione 		fCombineField->SetAlignment(B_ALIGN_RIGHT);
422a10cf76eSAxel Dörfler 
423a10cf76eSAxel Dörfler 		if (!multiMonSupport)
424df3f5bacSStephan Aßmus 			fCombineField->Hide();
425a10cf76eSAxel Dörfler 
426551c9f15SSiarzhuk Zharski 		fSwapDisplaysMenu = new BPopUpMenu("SwapDisplays",
427c9e8f97aSAdrien Destugues 			true, true);
428a10cf76eSAxel Dörfler 
429a10cf76eSAxel Dörfler 		// !order is important - we rely that boolean value == idx
4300efb8b66SJerome Duval 		BMessage *message = new BMessage(POP_SWAP_DISPLAYS_MSG);
431a10cf76eSAxel Dörfler 		message->AddBool("swap", false);
432c9e8f97aSAdrien Destugues 		fSwapDisplaysMenu->AddItem(new BMenuItem(B_TRANSLATE("no"), message));
433a10cf76eSAxel Dörfler 
434a10cf76eSAxel Dörfler 		message = new BMessage(POP_SWAP_DISPLAYS_MSG);
435a10cf76eSAxel Dörfler 		message->AddBool("swap", true);
436c9e8f97aSAdrien Destugues 		fSwapDisplaysMenu->AddItem(new BMenuItem(B_TRANSLATE("yes"), message));
437a10cf76eSAxel Dörfler 
438c9e8f97aSAdrien Destugues 		fSwapDisplaysField = new BMenuField("SwapMenu",
43910dfe897SAxel Dörfler 			B_TRANSLATE("Swap displays:"), fSwapDisplaysMenu);
4406048f541SJohn Scipione 		fSwapDisplaysField->SetAlignment(B_ALIGN_RIGHT);
441a10cf76eSAxel Dörfler 
442a10cf76eSAxel Dörfler 		if (!multiMonSupport)
443df3f5bacSStephan Aßmus 			fSwapDisplaysField->Hide();
444a10cf76eSAxel Dörfler 
445551c9f15SSiarzhuk Zharski 		fUseLaptopPanelMenu = new BPopUpMenu("UseLaptopPanel",
446c9e8f97aSAdrien Destugues 			true, true);
447a10cf76eSAxel Dörfler 
448a10cf76eSAxel Dörfler 		// !order is important - we rely that boolean value == idx
449a10cf76eSAxel Dörfler 		message = new BMessage(POP_USE_LAPTOP_PANEL_MSG);
450a10cf76eSAxel Dörfler 		message->AddBool("use", false);
451c9e8f97aSAdrien Destugues 		fUseLaptopPanelMenu->AddItem(new BMenuItem(B_TRANSLATE("if needed"),
452c9e8f97aSAdrien Destugues 			message));
453a10cf76eSAxel Dörfler 
454a10cf76eSAxel Dörfler 		message = new BMessage(POP_USE_LAPTOP_PANEL_MSG);
455a10cf76eSAxel Dörfler 		message->AddBool("use", true);
456c9e8f97aSAdrien Destugues 		fUseLaptopPanelMenu->AddItem(new BMenuItem(B_TRANSLATE("always"),
457c9e8f97aSAdrien Destugues 			message));
458a10cf76eSAxel Dörfler 
459b21d610eSAxel Dörfler 		fUseLaptopPanelField = new BMenuField("UseLaptopPanel",
46010dfe897SAxel Dörfler 			B_TRANSLATE("Use laptop panel:"), fUseLaptopPanelMenu);
4616048f541SJohn Scipione 		fUseLaptopPanelField->SetAlignment(B_ALIGN_RIGHT);
462a10cf76eSAxel Dörfler 
463a10cf76eSAxel Dörfler 		if (!useLaptopPanelSupport)
464df3f5bacSStephan Aßmus 			fUseLaptopPanelField->Hide();
465a10cf76eSAxel Dörfler 
466551c9f15SSiarzhuk Zharski 		fTVStandardMenu = new BPopUpMenu("TVStandard", true, true);
467a10cf76eSAxel Dörfler 
468a10cf76eSAxel Dörfler 		// arbitrary limit
469a10cf76eSAxel Dörfler 		uint32 i;
470a10cf76eSAxel Dörfler 		for (i = 0; i < 100; ++i) {
471a10cf76eSAxel Dörfler 			uint32 mode;
472a10cf76eSAxel Dörfler 			if (GetNthSupportedTVStandard(&screen, i, &mode) != B_OK)
473a10cf76eSAxel Dörfler 				break;
474a10cf76eSAxel Dörfler 
475a10cf76eSAxel Dörfler 			BString name = tv_standard_to_string(mode);
476a10cf76eSAxel Dörfler 
477a10cf76eSAxel Dörfler 			message = new BMessage(POP_TV_STANDARD_MSG);
478a10cf76eSAxel Dörfler 			message->AddInt32("tv_standard", mode);
479a10cf76eSAxel Dörfler 
480a10cf76eSAxel Dörfler 			fTVStandardMenu->AddItem(new BMenuItem(name.String(), message));
481a10cf76eSAxel Dörfler 		}
482a10cf76eSAxel Dörfler 
483c9e8f97aSAdrien Destugues 		fTVStandardField = new BMenuField("tv standard",
48410dfe897SAxel Dörfler 			B_TRANSLATE("Video format:"), fTVStandardMenu);
485df3f5bacSStephan Aßmus 		fTVStandardField->SetAlignment(B_ALIGN_RIGHT);
486a10cf76eSAxel Dörfler 
487b21d610eSAxel Dörfler 		if (!tvStandardSupport || i == 0)
488df3f5bacSStephan Aßmus 			fTVStandardField->Hide();
489a10cf76eSAxel Dörfler 	}
490a10cf76eSAxel Dörfler 
49125fd5c7bSAlex Wilson 	BLayoutBuilder::Group<>(outerControlsView)
4926048f541SJohn Scipione 		.AddGrid(B_USE_DEFAULT_SPACING, B_USE_SMALL_SPACING)
4936048f541SJohn Scipione 			.Add(fResolutionField->CreateLabelLayoutItem(), 0, 0)
4946048f541SJohn Scipione 			.Add(fResolutionField->CreateMenuBarLayoutItem(), 1, 0)
4956048f541SJohn Scipione 			.Add(fColorsField->CreateLabelLayoutItem(), 0, 1)
4966048f541SJohn Scipione 			.Add(fColorsField->CreateMenuBarLayoutItem(), 1, 1)
4976048f541SJohn Scipione 			.Add(fRefreshField->CreateLabelLayoutItem(), 0, 2)
4986048f541SJohn Scipione 			.Add(fRefreshField->CreateMenuBarLayoutItem(), 1, 2)
4996048f541SJohn Scipione 			.Add(fCombineField->CreateLabelLayoutItem(), 0, 3)
5006048f541SJohn Scipione 			.Add(fCombineField->CreateMenuBarLayoutItem(), 1, 3)
5016048f541SJohn Scipione 			.Add(fSwapDisplaysField->CreateLabelLayoutItem(), 0, 4)
5026048f541SJohn Scipione 			.Add(fSwapDisplaysField->CreateMenuBarLayoutItem(), 1, 4)
5036048f541SJohn Scipione 			.Add(fUseLaptopPanelField->CreateLabelLayoutItem(), 0, 5)
5046048f541SJohn Scipione 			.Add(fUseLaptopPanelField->CreateMenuBarLayoutItem(), 1, 5)
5056048f541SJohn Scipione 			.Add(fTVStandardField->CreateLabelLayoutItem(), 0, 6)
5066048f541SJohn Scipione 			.Add(fTVStandardField->CreateMenuBarLayoutItem(), 1, 6)
50725fd5c7bSAlex Wilson 		.End();
508df3f5bacSStephan Aßmus 
509abc649b8SWaldemar Kornewald 	// TODO: we don't support getting the screen's preferred settings
510abc649b8SWaldemar Kornewald 	/* fDefaultsButton = new BButton(buttonRect, "DefaultsButton", "Defaults",
511b21d610eSAxel Dörfler 		new BMessage(BUTTON_DEFAULTS_MSG));*/
512a10cf76eSAxel Dörfler 
513c9e8f97aSAdrien Destugues 	fApplyButton = new BButton("ApplyButton", B_TRANSLATE("Apply"),
514df3f5bacSStephan Aßmus 		new BMessage(BUTTON_APPLY_MSG));
515df3f5bacSStephan Aßmus 	fApplyButton->SetEnabled(false);
51625fd5c7bSAlex Wilson 	BLayoutBuilder::Group<>(outerControlsView)
517b21d610eSAxel Dörfler 		.AddGlue()
51825fd5c7bSAlex Wilson 			.AddGroup(B_HORIZONTAL)
51925fd5c7bSAlex Wilson 			.AddGlue()
52025fd5c7bSAlex Wilson 			.Add(fApplyButton);
521b21d610eSAxel Dörfler 
522c9e8f97aSAdrien Destugues 	fRevertButton = new BButton("RevertButton", B_TRANSLATE("Revert"),
523b21d610eSAxel Dörfler 		new BMessage(BUTTON_REVERT_MSG));
524b21d610eSAxel Dörfler 	fRevertButton->SetEnabled(false);
525b21d610eSAxel Dörfler 
5264666484fSJohn Scipione 	BLayoutBuilder::Group<>(this, B_VERTICAL, B_USE_DEFAULT_SPACING)
5274666484fSJohn Scipione 		.AddGroup(B_HORIZONTAL)
52883cc66b3SJohn Scipione 			.AddGroup(B_VERTICAL, 0)
52983cc66b3SJohn Scipione 				.AddStrut(floorf(controlsBox->TopBorderOffset()) - 1)
530b21d610eSAxel Dörfler 				.Add(screenBox)
53183cc66b3SJohn Scipione 				.End()
532b21d610eSAxel Dörfler 			.Add(controlsBox)
533b21d610eSAxel Dörfler 			.End()
5344666484fSJohn Scipione 		.AddGroup(B_HORIZONTAL, B_USE_DEFAULT_SPACING)
535b21d610eSAxel Dörfler 			.Add(fRevertButton)
5364666484fSJohn Scipione 			.AddGlue()
5374666484fSJohn Scipione 			.End()
5384666484fSJohn Scipione 		.SetInsets(B_USE_DEFAULT_SPACING);
539b21d610eSAxel Dörfler 
5405de171daSAxel Dörfler 	_UpdateControls();
54112966d04SAxel Dörfler 	_UpdateMonitor();
542a10cf76eSAxel Dörfler }
543a10cf76eSAxel Dörfler 
544a10cf76eSAxel Dörfler 
545a10cf76eSAxel Dörfler ScreenWindow::~ScreenWindow()
546a10cf76eSAxel Dörfler {
547a10cf76eSAxel Dörfler 	delete fSettings;
548a10cf76eSAxel Dörfler }
549a10cf76eSAxel Dörfler 
550a10cf76eSAxel Dörfler 
551a10cf76eSAxel Dörfler bool
552a10cf76eSAxel Dörfler ScreenWindow::QuitRequested()
553a10cf76eSAxel Dörfler {
554a10cf76eSAxel Dörfler 	fSettings->SetWindowFrame(Frame());
555199893c3SAxel Dörfler 
556199893c3SAxel Dörfler 	// Write mode of workspace 0 (the boot workspace) to the vesa settings file
557199893c3SAxel Dörfler 	screen_mode vesaMode;
558199893c3SAxel Dörfler 	if (fBootWorkspaceApplied && fScreenMode.Get(vesaMode, 0) == B_OK) {
559199893c3SAxel Dörfler 		status_t status = _WriteVesaModeFile(vesaMode);
56012580984SAxel Dörfler 		if (status < B_OK) {
561c9e8f97aSAdrien Destugues 			BString warning = B_TRANSLATE("Could not write VESA mode settings"
562c9e8f97aSAdrien Destugues 				" file:\n\t");
56312580984SAxel Dörfler 			warning << strerror(status);
564aed35104SHumdinger 			BAlert* alert = new BAlert(B_TRANSLATE("Warning"),
565aed35104SHumdinger 				warning.String(), B_TRANSLATE("OK"), NULL,
566aed35104SHumdinger 				NULL, B_WIDTH_AS_USUAL, B_WARNING_ALERT);
567aed35104SHumdinger 			alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE);
568aed35104SHumdinger 			alert->Go();
56912580984SAxel Dörfler 		}
57012580984SAxel Dörfler 	}
57112580984SAxel Dörfler 
572a10cf76eSAxel Dörfler 	be_app->PostMessage(B_QUIT_REQUESTED);
573a10cf76eSAxel Dörfler 
574a10cf76eSAxel Dörfler 	return BWindow::QuitRequested();
575a10cf76eSAxel Dörfler }
576a10cf76eSAxel Dörfler 
577a10cf76eSAxel Dörfler 
5785de171daSAxel Dörfler /*!	Update resolution list according to combine mode
5791fc4cb1fSAxel Dörfler 	(some resolutions may not be combinable due to memory restrictions).
580a10cf76eSAxel Dörfler */
581a10cf76eSAxel Dörfler void
5825de171daSAxel Dörfler ScreenWindow::_CheckResolutionMenu()
583a10cf76eSAxel Dörfler {
584a10cf76eSAxel Dörfler 	for (int32 i = 0; i < fResolutionMenu->CountItems(); i++)
585a10cf76eSAxel Dörfler 		fResolutionMenu->ItemAt(i)->SetEnabled(false);
586a10cf76eSAxel Dörfler 
587a10cf76eSAxel Dörfler 	for (int32 i = 0; i < fScreenMode.CountModes(); i++) {
588a10cf76eSAxel Dörfler 		screen_mode mode = fScreenMode.ModeAt(i);
589a10cf76eSAxel Dörfler 		if (mode.combine != fSelected.combine)
590a10cf76eSAxel Dörfler 			continue;
591a10cf76eSAxel Dörfler 
592a10cf76eSAxel Dörfler 		BString name;
593a10cf76eSAxel Dörfler 		name << mode.width << " x " << mode.height;
594a10cf76eSAxel Dörfler 
595a10cf76eSAxel Dörfler 		BMenuItem *item = fResolutionMenu->FindItem(name.String());
596a10cf76eSAxel Dörfler 		if (item != NULL)
597a10cf76eSAxel Dörfler 			item->SetEnabled(true);
598a10cf76eSAxel Dörfler 	}
599a10cf76eSAxel Dörfler }
600a10cf76eSAxel Dörfler 
601a10cf76eSAxel Dörfler 
6025de171daSAxel Dörfler /*!	Update color and refresh options according to current mode
6035de171daSAxel Dörfler 	(a color space is made active if there is any mode with
6045de171daSAxel Dörfler 	given resolution and this colour space; same applies for
6055de171daSAxel Dörfler 	refresh rate, though "Other…" is always possible)
606a10cf76eSAxel Dörfler */
607a10cf76eSAxel Dörfler void
6085de171daSAxel Dörfler ScreenWindow::_CheckColorMenu()
609a10cf76eSAxel Dörfler {
6101fc4cb1fSAxel Dörfler 	int32 supportsAnything = false;
6111fc4cb1fSAxel Dörfler 	int32 index = 0;
6121fc4cb1fSAxel Dörfler 
613a10cf76eSAxel Dörfler 	for (int32 i = 0; i < kColorSpaceCount; i++) {
6141fc4cb1fSAxel Dörfler 		if ((fSupportedColorSpaces & (1 << i)) == 0)
6151fc4cb1fSAxel Dörfler 			continue;
6161fc4cb1fSAxel Dörfler 
617a10cf76eSAxel Dörfler 		bool supported = false;
618a10cf76eSAxel Dörfler 
619a10cf76eSAxel Dörfler 		for (int32 j = 0; j < fScreenMode.CountModes(); j++) {
620a10cf76eSAxel Dörfler 			screen_mode mode = fScreenMode.ModeAt(j);
621a10cf76eSAxel Dörfler 
622a10cf76eSAxel Dörfler 			if (fSelected.width == mode.width
623a10cf76eSAxel Dörfler 				&& fSelected.height == mode.height
6241fc4cb1fSAxel Dörfler 				&& kColorSpaces[i].space == mode.space
625a10cf76eSAxel Dörfler 				&& fSelected.combine == mode.combine) {
6261fc4cb1fSAxel Dörfler 				supportsAnything = true;
627a10cf76eSAxel Dörfler 				supported = true;
628a10cf76eSAxel Dörfler 				break;
629a10cf76eSAxel Dörfler 			}
630a10cf76eSAxel Dörfler 		}
631a10cf76eSAxel Dörfler 
6321fc4cb1fSAxel Dörfler 		BMenuItem* item = fColorsMenu->ItemAt(index++);
633a10cf76eSAxel Dörfler 		if (item)
634a10cf76eSAxel Dörfler 			item->SetEnabled(supported);
635a10cf76eSAxel Dörfler 	}
6361fc4cb1fSAxel Dörfler 
6371fc4cb1fSAxel Dörfler 	fColorsField->SetEnabled(supportsAnything);
6381fc4cb1fSAxel Dörfler 
6391fc4cb1fSAxel Dörfler 	if (!supportsAnything)
6401fc4cb1fSAxel Dörfler 		return;
6411fc4cb1fSAxel Dörfler 
6421fc4cb1fSAxel Dörfler 	// Make sure a valid item is selected
6431fc4cb1fSAxel Dörfler 
6441fc4cb1fSAxel Dörfler 	BMenuItem* item = fColorsMenu->FindMarked();
6451fc4cb1fSAxel Dörfler 	bool changed = false;
6461fc4cb1fSAxel Dörfler 
6471fc4cb1fSAxel Dörfler 	if (item != fUserSelectedColorSpace) {
6481fc4cb1fSAxel Dörfler 		if (fUserSelectedColorSpace != NULL
6491fc4cb1fSAxel Dörfler 			&& fUserSelectedColorSpace->IsEnabled()) {
6501fc4cb1fSAxel Dörfler 			fUserSelectedColorSpace->SetMarked(true);
6511fc4cb1fSAxel Dörfler 			item = fUserSelectedColorSpace;
6521fc4cb1fSAxel Dörfler 			changed = true;
6531fc4cb1fSAxel Dörfler 		}
6541fc4cb1fSAxel Dörfler 	}
6551fc4cb1fSAxel Dörfler 	if (item != NULL && !item->IsEnabled()) {
6561fc4cb1fSAxel Dörfler 		// find the next best item
6571fc4cb1fSAxel Dörfler 		int32 index = fColorsMenu->IndexOf(item);
6581fc4cb1fSAxel Dörfler 		bool found = false;
6591fc4cb1fSAxel Dörfler 
6601fc4cb1fSAxel Dörfler 		for (int32 i = index + 1; i < fColorsMenu->CountItems(); i++) {
6611fc4cb1fSAxel Dörfler 			item = fColorsMenu->ItemAt(i);
6621fc4cb1fSAxel Dörfler 			if (item->IsEnabled()) {
6631fc4cb1fSAxel Dörfler 				found = true;
6641fc4cb1fSAxel Dörfler 				break;
6651fc4cb1fSAxel Dörfler 			}
6661fc4cb1fSAxel Dörfler 		}
6671fc4cb1fSAxel Dörfler 		if (!found) {
6681fc4cb1fSAxel Dörfler 			// search backwards as well
6691fc4cb1fSAxel Dörfler 			for (int32 i = index - 1; i >= 0; i--) {
6701fc4cb1fSAxel Dörfler 				item = fColorsMenu->ItemAt(i);
6711fc4cb1fSAxel Dörfler 				if (item->IsEnabled())
6721fc4cb1fSAxel Dörfler 					break;
6731fc4cb1fSAxel Dörfler 			}
6741fc4cb1fSAxel Dörfler 		}
6751fc4cb1fSAxel Dörfler 
6761fc4cb1fSAxel Dörfler 		item->SetMarked(true);
6771fc4cb1fSAxel Dörfler 		changed = true;
6781fc4cb1fSAxel Dörfler 	}
6791fc4cb1fSAxel Dörfler 
6801fc4cb1fSAxel Dörfler 	if (changed) {
6811fc4cb1fSAxel Dörfler 		// Update selected space
6821fc4cb1fSAxel Dörfler 
6831fc4cb1fSAxel Dörfler 		BMessage* message = item->Message();
6841fc4cb1fSAxel Dörfler 		int32 space;
6851fc4cb1fSAxel Dörfler 		if (message->FindInt32("space", &space) == B_OK) {
6861fc4cb1fSAxel Dörfler 			fSelected.space = (color_space)space;
6871fc4cb1fSAxel Dörfler 			_UpdateColorLabel();
6881fc4cb1fSAxel Dörfler 		}
6891fc4cb1fSAxel Dörfler 	}
690a10cf76eSAxel Dörfler }
691a10cf76eSAxel Dörfler 
692a10cf76eSAxel Dörfler 
6935de171daSAxel Dörfler /*!	Enable/disable refresh options according to current mode. */
694a10cf76eSAxel Dörfler void
6955de171daSAxel Dörfler ScreenWindow::_CheckRefreshMenu()
696a10cf76eSAxel Dörfler {
69729e8a73aSAxel Dörfler 	float min, max;
69829e8a73aSAxel Dörfler 	if (fScreenMode.GetRefreshLimits(fSelected, min, max) != B_OK || min == max)
69929e8a73aSAxel Dörfler 		return;
700a10cf76eSAxel Dörfler 
70129e8a73aSAxel Dörfler 	for (int32 i = fRefreshMenu->CountItems(); i-- > 0;) {
70229e8a73aSAxel Dörfler 		BMenuItem* item = fRefreshMenu->ItemAt(i);
70329e8a73aSAxel Dörfler 		BMessage* message = item->Message();
70429e8a73aSAxel Dörfler 		float refresh;
70529e8a73aSAxel Dörfler 		if (message != NULL && message->FindFloat("refresh", &refresh) == B_OK)
70629e8a73aSAxel Dörfler 			item->SetEnabled(refresh >= min && refresh <= max);
707a10cf76eSAxel Dörfler 	}
708a10cf76eSAxel Dörfler }
709a10cf76eSAxel Dörfler 
710a10cf76eSAxel Dörfler 
7115de171daSAxel Dörfler /*!	Activate appropriate menu item according to selected refresh rate */
712a10cf76eSAxel Dörfler void
7135de171daSAxel Dörfler ScreenWindow::_UpdateRefreshControl()
714a10cf76eSAxel Dörfler {
7157e44de36SRene Gollent 	for (int32 i = 0; i < fRefreshMenu->CountItems(); i++) {
7167e44de36SRene Gollent 		BMenuItem* item = fRefreshMenu->ItemAt(i);
7177e44de36SRene Gollent 		if (item->Message()->FindFloat("refresh") == fSelected.refresh) {
718a10cf76eSAxel Dörfler 			item->SetMarked(true);
71926747978SAdrien Destugues 			// "Other" items only contains a refresh rate when active
72026747978SAdrien Destugues 			fOtherRefresh->SetLabel(B_TRANSLATE("Other" B_UTF8_ELLIPSIS));
721a10cf76eSAxel Dörfler 			return;
722a10cf76eSAxel Dörfler 		}
7237e44de36SRene Gollent 	}
724a10cf76eSAxel Dörfler 
725a10cf76eSAxel Dörfler 	// this is a non-standard refresh rate
7267e44de36SRene Gollent 	if (fOtherRefresh != NULL) {
727a10cf76eSAxel Dörfler 		fOtherRefresh->Message()->ReplaceFloat("refresh", fSelected.refresh);
728a10cf76eSAxel Dörfler 		fOtherRefresh->SetMarked(true);
729a10cf76eSAxel Dörfler 
7307e44de36SRene Gollent 		BString string;
7317e44de36SRene Gollent 		refresh_rate_to_string(fSelected.refresh, string);
732a10cf76eSAxel Dörfler 		fRefreshMenu->Superitem()->SetLabel(string.String());
733a10cf76eSAxel Dörfler 
734c9e8f97aSAdrien Destugues 		string.Append(B_TRANSLATE("/other" B_UTF8_ELLIPSIS));
735a10cf76eSAxel Dörfler 		fOtherRefresh->SetLabel(string.String());
736a10cf76eSAxel Dörfler 	}
7377e44de36SRene Gollent }
738a10cf76eSAxel Dörfler 
739a10cf76eSAxel Dörfler 
740a10cf76eSAxel Dörfler void
7415de171daSAxel Dörfler ScreenWindow::_UpdateMonitorView()
742a10cf76eSAxel Dörfler {
743a10cf76eSAxel Dörfler 	BMessage updateMessage(UPDATE_DESKTOP_MSG);
744a10cf76eSAxel Dörfler 	updateMessage.AddInt32("width", fSelected.width);
745a10cf76eSAxel Dörfler 	updateMessage.AddInt32("height", fSelected.height);
746a10cf76eSAxel Dörfler 
747a10cf76eSAxel Dörfler 	PostMessage(&updateMessage, fMonitorView);
748a10cf76eSAxel Dörfler }
749a10cf76eSAxel Dörfler 
750a10cf76eSAxel Dörfler 
751a10cf76eSAxel Dörfler void
7525de171daSAxel Dörfler ScreenWindow::_UpdateControls()
753a10cf76eSAxel Dörfler {
754b21d610eSAxel Dörfler 	_UpdateWorkspaceButtons();
755b21d610eSAxel Dörfler 
756a10cf76eSAxel Dörfler 	BMenuItem* item = fSwapDisplaysMenu->ItemAt((int32)fSelected.swap_displays);
757c33a865cSJohn Scipione 	if (item != NULL && !item->IsMarked())
758a10cf76eSAxel Dörfler 		item->SetMarked(true);
759a10cf76eSAxel Dörfler 
760a10cf76eSAxel Dörfler 	item = fUseLaptopPanelMenu->ItemAt((int32)fSelected.use_laptop_panel);
761c33a865cSJohn Scipione 	if (item != NULL && !item->IsMarked())
762a10cf76eSAxel Dörfler 		item->SetMarked(true);
763a10cf76eSAxel Dörfler 
764a10cf76eSAxel Dörfler 	for (int32 i = 0; i < fTVStandardMenu->CountItems(); i++) {
765a10cf76eSAxel Dörfler 		item = fTVStandardMenu->ItemAt(i);
766a10cf76eSAxel Dörfler 
767a10cf76eSAxel Dörfler 		uint32 tvStandard;
768a10cf76eSAxel Dörfler 		item->Message()->FindInt32("tv_standard", (int32 *)&tvStandard);
769a10cf76eSAxel Dörfler 		if (tvStandard == fSelected.tv_standard) {
770a10cf76eSAxel Dörfler 			if (!item->IsMarked())
771a10cf76eSAxel Dörfler 				item->SetMarked(true);
772a10cf76eSAxel Dörfler 			break;
773a10cf76eSAxel Dörfler 		}
774a10cf76eSAxel Dörfler 	}
775a10cf76eSAxel Dörfler 
7765de171daSAxel Dörfler 	_CheckResolutionMenu();
7775de171daSAxel Dörfler 	_CheckColorMenu();
7785de171daSAxel Dörfler 	_CheckRefreshMenu();
779a10cf76eSAxel Dörfler 
780a10cf76eSAxel Dörfler 	BString string;
781a10cf76eSAxel Dörfler 	resolution_to_string(fSelected, string);
782a10cf76eSAxel Dörfler 	item = fResolutionMenu->FindItem(string.String());
783a10cf76eSAxel Dörfler 
784a10cf76eSAxel Dörfler 	if (item != NULL) {
785a10cf76eSAxel Dörfler 		if (!item->IsMarked())
786a10cf76eSAxel Dörfler 			item->SetMarked(true);
787a10cf76eSAxel Dörfler 	} else {
788a10cf76eSAxel Dörfler 		// this is bad luck - if mode has been set via screen references,
789a10cf76eSAxel Dörfler 		// this case cannot occur; there are three possible solutions:
790a10cf76eSAxel Dörfler 		// 1. add a new resolution to list
791a10cf76eSAxel Dörfler 		//    - we had to remove it as soon as a "valid" one is selected
792a10cf76eSAxel Dörfler 		//    - we don't know which frequencies/bit depths are supported
793a10cf76eSAxel Dörfler 		//    - as long as we haven't the GMT formula to create
794a10cf76eSAxel Dörfler 		//      parameters for any resolution given, we cannot
795a10cf76eSAxel Dörfler 		//      really set current mode - it's just not in the list
796a10cf76eSAxel Dörfler 		// 2. choose nearest resolution
797a10cf76eSAxel Dörfler 		//    - probably a good idea, but implies coding and testing
798a10cf76eSAxel Dörfler 		// 3. choose lowest resolution
799a10cf76eSAxel Dörfler 		//    - do you really think we are so lazy? yes, we are
800a10cf76eSAxel Dörfler 		item = fResolutionMenu->ItemAt(0);
801a10cf76eSAxel Dörfler 		if (item)
802a10cf76eSAxel Dörfler 			item->SetMarked(true);
803a10cf76eSAxel Dörfler 
804a10cf76eSAxel Dörfler 		// okay - at least we set menu label to active resolution
805a10cf76eSAxel Dörfler 		fResolutionMenu->Superitem()->SetLabel(string.String());
806a10cf76eSAxel Dörfler 	}
807a10cf76eSAxel Dörfler 
808a10cf76eSAxel Dörfler 	// mark active combine mode
809a10cf76eSAxel Dörfler 	for (int32 i = 0; i < kCombineModeCount; i++) {
810a10cf76eSAxel Dörfler 		if (kCombineModes[i].mode == fSelected.combine) {
811a10cf76eSAxel Dörfler 			item = fCombineMenu->ItemAt(i);
812c33a865cSJohn Scipione 			if (item != NULL && !item->IsMarked())
813a10cf76eSAxel Dörfler 				item->SetMarked(true);
814a10cf76eSAxel Dörfler 			break;
815a10cf76eSAxel Dörfler 		}
816a10cf76eSAxel Dörfler 	}
817a10cf76eSAxel Dörfler 
818a10cf76eSAxel Dörfler 	item = fColorsMenu->ItemAt(0);
819a10cf76eSAxel Dörfler 
8201fc4cb1fSAxel Dörfler 	for (int32 i = 0, index = 0; i <  kColorSpaceCount; i++) {
8211fc4cb1fSAxel Dörfler 		if ((fSupportedColorSpaces & (1 << i)) == 0)
8221fc4cb1fSAxel Dörfler 			continue;
8231fc4cb1fSAxel Dörfler 
8241fc4cb1fSAxel Dörfler 		if (kColorSpaces[i].space == fSelected.space) {
8251fc4cb1fSAxel Dörfler 			item = fColorsMenu->ItemAt(index);
826a10cf76eSAxel Dörfler 			break;
827a10cf76eSAxel Dörfler 		}
8281fc4cb1fSAxel Dörfler 
8291fc4cb1fSAxel Dörfler 		index++;
830a10cf76eSAxel Dörfler 	}
831a10cf76eSAxel Dörfler 
832c33a865cSJohn Scipione 	if (item != NULL && !item->IsMarked())
833a10cf76eSAxel Dörfler 		item->SetMarked(true);
834a10cf76eSAxel Dörfler 
8351fc4cb1fSAxel Dörfler 	_UpdateColorLabel();
8365de171daSAxel Dörfler 	_UpdateMonitorView();
8375de171daSAxel Dörfler 	_UpdateRefreshControl();
838a10cf76eSAxel Dörfler 
8395de171daSAxel Dörfler 	_CheckApplyEnabled();
840a10cf76eSAxel Dörfler }
841a10cf76eSAxel Dörfler 
842a10cf76eSAxel Dörfler 
84312580984SAxel Dörfler /*! Reflect active mode in chosen settings */
844a10cf76eSAxel Dörfler void
8455de171daSAxel Dörfler ScreenWindow::_UpdateActiveMode()
846a10cf76eSAxel Dörfler {
847c491b5adSJohn Scipione 	_UpdateActiveMode(current_workspace());
848c491b5adSJohn Scipione }
849c491b5adSJohn Scipione 
850c491b5adSJohn Scipione 
851c491b5adSJohn Scipione void
852c491b5adSJohn Scipione ScreenWindow::_UpdateActiveMode(int32 workspace)
853c491b5adSJohn Scipione {
85412580984SAxel Dörfler 	// Usually, this function gets called after a mode
855a10cf76eSAxel Dörfler 	// has been set manually; still, as the graphics driver
856a10cf76eSAxel Dörfler 	// is free to fiddle with mode passed, we better ask
857a10cf76eSAxel Dörfler 	// what kind of mode we actually got
858c491b5adSJohn Scipione 	if (fScreenMode.Get(fActive, workspace) == B_OK) {
859a10cf76eSAxel Dörfler 		fSelected = fActive;
860a10cf76eSAxel Dörfler 
86112966d04SAxel Dörfler 		_UpdateMonitor();
862c491b5adSJohn Scipione 		_BuildSupportedColorSpaces();
8635de171daSAxel Dörfler 		_UpdateControls();
864a10cf76eSAxel Dörfler 	}
865c491b5adSJohn Scipione }
866a10cf76eSAxel Dörfler 
867a10cf76eSAxel Dörfler 
868a10cf76eSAxel Dörfler void
869b21d610eSAxel Dörfler ScreenWindow::_UpdateWorkspaceButtons()
870b21d610eSAxel Dörfler {
871b21d610eSAxel Dörfler 	uint32 columns;
872b21d610eSAxel Dörfler 	uint32 rows;
873b21d610eSAxel Dörfler 	BPrivate::get_workspaces_layout(&columns, &rows);
874b21d610eSAxel Dörfler 
875b21d610eSAxel Dörfler 	char text[32];
8765084d0d4SAlex Smith 	snprintf(text, sizeof(text), "%" B_PRId32, columns);
877b21d610eSAxel Dörfler 	fColumnsControl->SetText(text);
878b21d610eSAxel Dörfler 
8795084d0d4SAlex Smith 	snprintf(text, sizeof(text), "%" B_PRId32, rows);
880b21d610eSAxel Dörfler 	fRowsControl->SetText(text);
881b21d610eSAxel Dörfler 
882b21d610eSAxel Dörfler 	_GetColumnRowButton(true, false)->SetEnabled(columns != 1 && rows != 32);
883b21d610eSAxel Dörfler 	_GetColumnRowButton(true, true)->SetEnabled((columns + 1) * rows < 32);
884b21d610eSAxel Dörfler 	_GetColumnRowButton(false, false)->SetEnabled(rows != 1 && columns != 32);
885b21d610eSAxel Dörfler 	_GetColumnRowButton(false, true)->SetEnabled(columns * (rows + 1) < 32);
886b21d610eSAxel Dörfler }
887b21d610eSAxel Dörfler 
888b21d610eSAxel Dörfler 
889b21d610eSAxel Dörfler void
890a10cf76eSAxel Dörfler ScreenWindow::ScreenChanged(BRect frame, color_space mode)
891a10cf76eSAxel Dörfler {
892a10cf76eSAxel Dörfler 	// move window on screen, if necessary
893a10cf76eSAxel Dörfler 	if (frame.right <= Frame().right
894a10cf76eSAxel Dörfler 		&& frame.bottom <= Frame().bottom) {
895a10cf76eSAxel Dörfler 		MoveTo((frame.Width() - Frame().Width()) / 2,
896a10cf76eSAxel Dörfler 			(frame.Height() - Frame().Height()) / 2);
897a10cf76eSAxel Dörfler 	}
898a10cf76eSAxel Dörfler }
899a10cf76eSAxel Dörfler 
900a10cf76eSAxel Dörfler 
901a10cf76eSAxel Dörfler void
902a10cf76eSAxel Dörfler ScreenWindow::WorkspaceActivated(int32 workspace, bool state)
903a10cf76eSAxel Dörfler {
904c491b5adSJohn Scipione 	if (fScreenMode.GetOriginalMode(fOriginal, workspace) == B_OK) {
905c491b5adSJohn Scipione 		_UpdateActiveMode(workspace);
906a10cf76eSAxel Dörfler 
9076edaa0f6SStefano Ceccherini 		BMessage message(UPDATE_DESKTOP_COLOR_MSG);
9086edaa0f6SStefano Ceccherini 		PostMessage(&message, fMonitorView);
909a10cf76eSAxel Dörfler 	}
910c491b5adSJohn Scipione }
911a10cf76eSAxel Dörfler 
912a10cf76eSAxel Dörfler 
913a10cf76eSAxel Dörfler void
914a10cf76eSAxel Dörfler ScreenWindow::MessageReceived(BMessage* message)
915a10cf76eSAxel Dörfler {
916a10cf76eSAxel Dörfler 	switch (message->what) {
917a10cf76eSAxel Dörfler 		case WORKSPACE_CHECK_MSG:
9185de171daSAxel Dörfler 			_CheckApplyEnabled();
919a10cf76eSAxel Dörfler 			break;
920a10cf76eSAxel Dörfler 
921b21d610eSAxel Dörfler 		case kMsgWorkspaceLayoutChanged:
922a10cf76eSAxel Dörfler 		{
923b21d610eSAxel Dörfler 			int32 deltaX = 0;
924b21d610eSAxel Dörfler 			int32 deltaY = 0;
925b21d610eSAxel Dörfler 			message->FindInt32("delta_x", &deltaX);
926b21d610eSAxel Dörfler 			message->FindInt32("delta_y", &deltaY);
927b21d610eSAxel Dörfler 
928b21d610eSAxel Dörfler 			if (deltaX == 0 && deltaY == 0)
929b21d610eSAxel Dörfler 				break;
930b21d610eSAxel Dörfler 
931b21d610eSAxel Dörfler 			uint32 newColumns;
932b21d610eSAxel Dörfler 			uint32 newRows;
933b21d610eSAxel Dörfler 			BPrivate::get_workspaces_layout(&newColumns, &newRows);
934b21d610eSAxel Dörfler 
935b21d610eSAxel Dörfler 			newColumns += deltaX;
936b21d610eSAxel Dörfler 			newRows += deltaY;
937b21d610eSAxel Dörfler 			BPrivate::set_workspaces_layout(newColumns, newRows);
938b21d610eSAxel Dörfler 
939b21d610eSAxel Dörfler 			_UpdateWorkspaceButtons();
9405de171daSAxel Dörfler 			_CheckApplyEnabled();
941b21d610eSAxel Dörfler 			break;
942abc649b8SWaldemar Kornewald 		}
943b21d610eSAxel Dörfler 
944b21d610eSAxel Dörfler 		case kMsgWorkspaceColumnsChanged:
945b21d610eSAxel Dörfler 		{
946b21d610eSAxel Dörfler 			uint32 newColumns = strtoul(fColumnsControl->Text(), NULL, 10);
947b21d610eSAxel Dörfler 
948b21d610eSAxel Dörfler 			uint32 rows;
949b21d610eSAxel Dörfler 			BPrivate::get_workspaces_layout(NULL, &rows);
950b21d610eSAxel Dörfler 			BPrivate::set_workspaces_layout(newColumns, rows);
951b21d610eSAxel Dörfler 
952b21d610eSAxel Dörfler 			_UpdateWorkspaceButtons();
953b21d610eSAxel Dörfler 			_CheckApplyEnabled();
954b21d610eSAxel Dörfler 			break;
955b21d610eSAxel Dörfler 		}
956b21d610eSAxel Dörfler 
957b21d610eSAxel Dörfler 		case kMsgWorkspaceRowsChanged:
958b21d610eSAxel Dörfler 		{
959b21d610eSAxel Dörfler 			uint32 newRows = strtoul(fRowsControl->Text(), NULL, 10);
960b21d610eSAxel Dörfler 
961b21d610eSAxel Dörfler 			uint32 columns;
962b21d610eSAxel Dörfler 			BPrivate::get_workspaces_layout(&columns, NULL);
963b21d610eSAxel Dörfler 			BPrivate::set_workspaces_layout(columns, newRows);
964b21d610eSAxel Dörfler 
965b21d610eSAxel Dörfler 			_UpdateWorkspaceButtons();
966b21d610eSAxel Dörfler 			_CheckApplyEnabled();
967a10cf76eSAxel Dörfler 			break;
968a10cf76eSAxel Dörfler 		}
969a10cf76eSAxel Dörfler 
970a10cf76eSAxel Dörfler 		case POP_RESOLUTION_MSG:
971a10cf76eSAxel Dörfler 		{
972a10cf76eSAxel Dörfler 			message->FindInt32("width", &fSelected.width);
973a10cf76eSAxel Dörfler 			message->FindInt32("height", &fSelected.height);
974a10cf76eSAxel Dörfler 
9755de171daSAxel Dörfler 			_CheckColorMenu();
9765de171daSAxel Dörfler 			_CheckRefreshMenu();
977a10cf76eSAxel Dörfler 
9785de171daSAxel Dörfler 			_UpdateMonitorView();
9795de171daSAxel Dörfler 			_UpdateRefreshControl();
980a10cf76eSAxel Dörfler 
9815de171daSAxel Dörfler 			_CheckApplyEnabled();
982a10cf76eSAxel Dörfler 			break;
983a10cf76eSAxel Dörfler 		}
984a10cf76eSAxel Dörfler 
985a10cf76eSAxel Dörfler 		case POP_COLORS_MSG:
986a10cf76eSAxel Dörfler 		{
9871fc4cb1fSAxel Dörfler 			int32 space;
9881fc4cb1fSAxel Dörfler 			if (message->FindInt32("space", &space) != B_OK)
9891fc4cb1fSAxel Dörfler 				break;
990a10cf76eSAxel Dörfler 
9911fc4cb1fSAxel Dörfler 			int32 index;
9921fc4cb1fSAxel Dörfler 			if (message->FindInt32("index", &index) == B_OK
9931fc4cb1fSAxel Dörfler 				&& fColorsMenu->ItemAt(index) != NULL)
9941fc4cb1fSAxel Dörfler 				fUserSelectedColorSpace = fColorsMenu->ItemAt(index);
9951fc4cb1fSAxel Dörfler 
9961fc4cb1fSAxel Dörfler 			fSelected.space = (color_space)space;
9971fc4cb1fSAxel Dörfler 			_UpdateColorLabel();
998a10cf76eSAxel Dörfler 
9995de171daSAxel Dörfler 			_CheckApplyEnabled();
1000a10cf76eSAxel Dörfler 			break;
1001a10cf76eSAxel Dörfler 		}
1002a10cf76eSAxel Dörfler 
1003a10cf76eSAxel Dörfler 		case POP_REFRESH_MSG:
1004a40498e2SWaldemar Kornewald 		{
1005a10cf76eSAxel Dörfler 			message->FindFloat("refresh", &fSelected.refresh);
1006c9e8f97aSAdrien Destugues 			fOtherRefresh->SetLabel(B_TRANSLATE("Other" B_UTF8_ELLIPSIS));
10071fc4cb1fSAxel Dörfler 				// revert "Other…" label - it might have a refresh rate prefix
1008a10cf76eSAxel Dörfler 
10095de171daSAxel Dörfler 			_CheckApplyEnabled();
1010a10cf76eSAxel Dörfler 			break;
1011a40498e2SWaldemar Kornewald 		}
1012a10cf76eSAxel Dörfler 
1013a10cf76eSAxel Dörfler 		case POP_OTHER_REFRESH_MSG:
1014a10cf76eSAxel Dörfler 		{
101529e8a73aSAxel Dörfler 			// make sure menu shows something useful
10165de171daSAxel Dörfler 			_UpdateRefreshControl();
1017a10cf76eSAxel Dörfler 
101829e8a73aSAxel Dörfler 			float min = 0, max = 999;
101929e8a73aSAxel Dörfler 			fScreenMode.GetRefreshLimits(fSelected, min, max);
102029e8a73aSAxel Dörfler 			if (min < gMinRefresh)
102129e8a73aSAxel Dörfler 				min = gMinRefresh;
102229e8a73aSAxel Dörfler 			if (max > gMaxRefresh)
102329e8a73aSAxel Dörfler 				max = gMaxRefresh;
102429e8a73aSAxel Dörfler 
102570a2b1b5SAxel Dörfler 			monitor_info info;
102670a2b1b5SAxel Dörfler 			if (fScreenMode.GetMonitorInfo(info) == B_OK) {
102770a2b1b5SAxel Dörfler 				min = max_c(info.min_vertical_frequency, min);
102870a2b1b5SAxel Dörfler 				max = min_c(info.max_vertical_frequency, max);
102970a2b1b5SAxel Dörfler 			}
103070a2b1b5SAxel Dörfler 
1031c5d10f7aSAxel Dörfler 			RefreshWindow *fRefreshWindow = new RefreshWindow(
103270a2b1b5SAxel Dörfler 				fRefreshField->ConvertToScreen(B_ORIGIN), fSelected.refresh,
103370a2b1b5SAxel Dörfler 				min, max);
1034a10cf76eSAxel Dörfler 			fRefreshWindow->Show();
1035a10cf76eSAxel Dörfler 			break;
1036a10cf76eSAxel Dörfler 		}
1037a10cf76eSAxel Dörfler 
1038a10cf76eSAxel Dörfler 		case SET_CUSTOM_REFRESH_MSG:
1039a10cf76eSAxel Dörfler 		{
1040a10cf76eSAxel Dörfler 			// user pressed "done" in "Other…" refresh dialog;
1041a10cf76eSAxel Dörfler 			// select the refresh rate chosen
1042a10cf76eSAxel Dörfler 			message->FindFloat("refresh", &fSelected.refresh);
1043a10cf76eSAxel Dörfler 
10445de171daSAxel Dörfler 			_UpdateRefreshControl();
10455de171daSAxel Dörfler 			_CheckApplyEnabled();
1046a10cf76eSAxel Dörfler 			break;
1047a10cf76eSAxel Dörfler 		}
1048a10cf76eSAxel Dörfler 
1049a10cf76eSAxel Dörfler 		case POP_COMBINE_DISPLAYS_MSG:
1050a10cf76eSAxel Dörfler 		{
1051a10cf76eSAxel Dörfler 			// new combine mode has bee chosen
1052a10cf76eSAxel Dörfler 			int32 mode;
1053a10cf76eSAxel Dörfler 			if (message->FindInt32("mode", &mode) == B_OK)
1054a10cf76eSAxel Dörfler 				fSelected.combine = (combine_mode)mode;
1055a10cf76eSAxel Dörfler 
10565de171daSAxel Dörfler 			_CheckResolutionMenu();
10575de171daSAxel Dörfler 			_CheckApplyEnabled();
1058a10cf76eSAxel Dörfler 			break;
1059a10cf76eSAxel Dörfler 		}
1060a10cf76eSAxel Dörfler 
1061a10cf76eSAxel Dörfler 		case POP_SWAP_DISPLAYS_MSG:
1062a10cf76eSAxel Dörfler 			message->FindBool("swap", &fSelected.swap_displays);
10635de171daSAxel Dörfler 			_CheckApplyEnabled();
1064a10cf76eSAxel Dörfler 			break;
1065a10cf76eSAxel Dörfler 
1066a10cf76eSAxel Dörfler 		case POP_USE_LAPTOP_PANEL_MSG:
1067a10cf76eSAxel Dörfler 			message->FindBool("use", &fSelected.use_laptop_panel);
10685de171daSAxel Dörfler 			_CheckApplyEnabled();
1069a10cf76eSAxel Dörfler 			break;
1070a10cf76eSAxel Dörfler 
1071a10cf76eSAxel Dörfler 		case POP_TV_STANDARD_MSG:
1072a10cf76eSAxel Dörfler 			message->FindInt32("tv_standard", (int32 *)&fSelected.tv_standard);
10735de171daSAxel Dörfler 			_CheckApplyEnabled();
1074a10cf76eSAxel Dörfler 			break;
1075a10cf76eSAxel Dörfler 
1076df3f5bacSStephan Aßmus 		case BUTTON_LAUNCH_BACKGROUNDS_MSG:
10776f095d6aSRyan Leavengood 			if (be_roster->Launch(kBackgroundsSignature) == B_ALREADY_RUNNING) {
10786f095d6aSRyan Leavengood 				app_info info;
10796f095d6aSRyan Leavengood 				be_roster->GetAppInfo(kBackgroundsSignature, &info);
10806f095d6aSRyan Leavengood 				be_roster->ActivateApp(info.team);
10816f095d6aSRyan Leavengood 			}
1082df3f5bacSStephan Aßmus 			break;
1083df3f5bacSStephan Aßmus 
1084a10cf76eSAxel Dörfler 		case BUTTON_DEFAULTS_MSG:
1085a10cf76eSAxel Dörfler 		{
10864be51fe3SWaldemar Kornewald 			// TODO: get preferred settings of screen
1087a10cf76eSAxel Dörfler 			fSelected.width = 640;
1088a10cf76eSAxel Dörfler 			fSelected.height = 480;
1089a10cf76eSAxel Dörfler 			fSelected.space = B_CMAP8;
1090a10cf76eSAxel Dörfler 			fSelected.refresh = 60.0;
1091a10cf76eSAxel Dörfler 			fSelected.combine = kCombineDisable;
1092a10cf76eSAxel Dörfler 			fSelected.swap_displays = false;
1093a10cf76eSAxel Dörfler 			fSelected.use_laptop_panel = false;
1094a10cf76eSAxel Dörfler 			fSelected.tv_standard = 0;
1095a10cf76eSAxel Dörfler 
1096b21d610eSAxel Dörfler 			// TODO: workspace defaults
1097abc649b8SWaldemar Kornewald 
10985de171daSAxel Dörfler 			_UpdateControls();
1099a10cf76eSAxel Dörfler 			break;
1100a10cf76eSAxel Dörfler 		}
1101a10cf76eSAxel Dörfler 
110210e9b12fSWaldemar Kornewald 		case BUTTON_UNDO_MSG:
110361c5c89bSAxel Dörfler 			fUndoScreenMode.Revert();
11045de171daSAxel Dörfler 			_UpdateActiveMode();
1105abc649b8SWaldemar Kornewald 			break;
1106abc649b8SWaldemar Kornewald 
1107abc649b8SWaldemar Kornewald 		case BUTTON_REVERT_MSG:
1108abc649b8SWaldemar Kornewald 		{
1109abc649b8SWaldemar Kornewald 			fModified = false;
1110199893c3SAxel Dörfler 			fBootWorkspaceApplied = false;
1111abc649b8SWaldemar Kornewald 
1112b21d610eSAxel Dörfler 			// ScreenMode::Revert() assumes that we first set the correct
1113b21d610eSAxel Dörfler 			// number of workspaces
1114b21d610eSAxel Dörfler 
1115b21d610eSAxel Dörfler 			BPrivate::set_workspaces_layout(fOriginalWorkspacesColumns,
1116b21d610eSAxel Dörfler 				fOriginalWorkspacesRows);
1117b21d610eSAxel Dörfler 			_UpdateWorkspaceButtons();
1118b21d610eSAxel Dörfler 
1119a10cf76eSAxel Dörfler 			fScreenMode.Revert();
11205de171daSAxel Dörfler 			_UpdateActiveMode();
1121a10cf76eSAxel Dörfler 			break;
1122abc649b8SWaldemar Kornewald 		}
1123a10cf76eSAxel Dörfler 
1124a10cf76eSAxel Dörfler 		case BUTTON_APPLY_MSG:
11255de171daSAxel Dörfler 			_Apply();
1126a10cf76eSAxel Dörfler 			break;
1127a10cf76eSAxel Dörfler 
1128abc649b8SWaldemar Kornewald 		case MAKE_INITIAL_MSG:
1129abc649b8SWaldemar Kornewald 			// user pressed "keep" in confirmation dialog
1130abc649b8SWaldemar Kornewald 			fModified = true;
11315de171daSAxel Dörfler 			_UpdateActiveMode();
1132a10cf76eSAxel Dörfler 			break;
1133a10cf76eSAxel Dörfler 
1134a10cf76eSAxel Dörfler 		default:
1135a10cf76eSAxel Dörfler 			BWindow::MessageReceived(message);
1136a10cf76eSAxel Dörfler 			break;
1137a10cf76eSAxel Dörfler 	}
1138a10cf76eSAxel Dörfler }
1139a10cf76eSAxel Dörfler 
1140a10cf76eSAxel Dörfler 
114112580984SAxel Dörfler status_t
114212580984SAxel Dörfler ScreenWindow::_WriteVesaModeFile(const screen_mode& mode) const
114312580984SAxel Dörfler {
114412580984SAxel Dörfler 	BPath path;
114512580984SAxel Dörfler 	status_t status = find_directory(B_USER_SETTINGS_DIRECTORY, &path, true);
114612580984SAxel Dörfler 	if (status < B_OK)
114712580984SAxel Dörfler 		return status;
114812580984SAxel Dörfler 
114912580984SAxel Dörfler 	path.Append("kernel/drivers");
115012580984SAxel Dörfler 	status = create_directory(path.Path(), 0755);
115112580984SAxel Dörfler 	if (status < B_OK)
115212580984SAxel Dörfler 		return status;
115312580984SAxel Dörfler 
115412580984SAxel Dörfler 	path.Append("vesa");
115512580984SAxel Dörfler 	BFile file;
115612580984SAxel Dörfler 	status = file.SetTo(path.Path(), B_CREATE_FILE | B_WRITE_ONLY | B_ERASE_FILE);
115712580984SAxel Dörfler 	if (status < B_OK)
115812580984SAxel Dörfler 		return status;
115912580984SAxel Dörfler 
116012580984SAxel Dörfler 	char buffer[256];
11615084d0d4SAlex Smith 	snprintf(buffer, sizeof(buffer), "mode %" B_PRId32 " %" B_PRId32 " %"
11625084d0d4SAlex Smith 		B_PRId32 "\n", mode.width, mode.height, mode.BitsPerPixel());
116312580984SAxel Dörfler 
116412580984SAxel Dörfler 	ssize_t bytesWritten = file.Write(buffer, strlen(buffer));
116512580984SAxel Dörfler 	if (bytesWritten < B_OK)
116612580984SAxel Dörfler 		return bytesWritten;
116712580984SAxel Dörfler 
116812580984SAxel Dörfler 	return B_OK;
116912580984SAxel Dörfler }
117012580984SAxel Dörfler 
117112580984SAxel Dörfler 
1172b21d610eSAxel Dörfler BButton*
1173b21d610eSAxel Dörfler ScreenWindow::_CreateColumnRowButton(bool columns, bool plus)
1174b21d610eSAxel Dörfler {
1175b21d610eSAxel Dörfler 	BMessage* message = new BMessage(kMsgWorkspaceLayoutChanged);
1176b21d610eSAxel Dörfler 	message->AddInt32("delta_x", columns ? (plus ? 1 : -1) : 0);
1177b21d610eSAxel Dörfler 	message->AddInt32("delta_y", !columns ? (plus ? 1 : -1) : 0);
1178b21d610eSAxel Dörfler 
1179a2bf375cSJohn Scipione 	BButton* button = new BButton(plus ? "+" : "\xe2\x88\x92", message);
1180b21d610eSAxel Dörfler 	button->SetFontSize(be_plain_font->Size() * 0.9);
1181b21d610eSAxel Dörfler 
1182b21d610eSAxel Dörfler 	BSize size = button->MinSize();
1183b21d610eSAxel Dörfler 	size.width = button->StringWidth("+") + 16;
1184b21d610eSAxel Dörfler 	button->SetExplicitMinSize(size);
1185b21d610eSAxel Dörfler 	button->SetExplicitMaxSize(size);
1186b21d610eSAxel Dörfler 
1187b21d610eSAxel Dörfler 	fWorkspacesButtons[(columns ? 0 : 2) + (plus ? 1 : 0)] = button;
1188b21d610eSAxel Dörfler 	return button;
1189b21d610eSAxel Dörfler }
1190b21d610eSAxel Dörfler 
1191b21d610eSAxel Dörfler 
1192b21d610eSAxel Dörfler BButton*
1193b21d610eSAxel Dörfler ScreenWindow::_GetColumnRowButton(bool columns, bool plus)
1194b21d610eSAxel Dörfler {
1195b21d610eSAxel Dörfler 	return fWorkspacesButtons[(columns ? 0 : 2) + (plus ? 1 : 0)];
1196b21d610eSAxel Dörfler }
1197b21d610eSAxel Dörfler 
1198b21d610eSAxel Dörfler 
1199a10cf76eSAxel Dörfler void
12001fc4cb1fSAxel Dörfler ScreenWindow::_BuildSupportedColorSpaces()
12011fc4cb1fSAxel Dörfler {
12021fc4cb1fSAxel Dörfler 	fSupportedColorSpaces = 0;
12031fc4cb1fSAxel Dörfler 
12041fc4cb1fSAxel Dörfler 	for (int32 i = 0; i < kColorSpaceCount; i++) {
12051fc4cb1fSAxel Dörfler 		for (int32 j = 0; j < fScreenMode.CountModes(); j++) {
12061fc4cb1fSAxel Dörfler 			if (fScreenMode.ModeAt(j).space == kColorSpaces[i].space) {
12071fc4cb1fSAxel Dörfler 				fSupportedColorSpaces |= 1 << i;
12081fc4cb1fSAxel Dörfler 				break;
12091fc4cb1fSAxel Dörfler 			}
12101fc4cb1fSAxel Dörfler 		}
12111fc4cb1fSAxel Dörfler 	}
12121fc4cb1fSAxel Dörfler }
12131fc4cb1fSAxel Dörfler 
12141fc4cb1fSAxel Dörfler 
12151fc4cb1fSAxel Dörfler void
12165de171daSAxel Dörfler ScreenWindow::_CheckApplyEnabled()
1217a10cf76eSAxel Dörfler {
121827c43a2dSRene Gollent 	fApplyButton->SetEnabled(fSelected != fActive
121927c43a2dSRene Gollent 		|| fAllWorkspacesItem->IsMarked());
1220b21d610eSAxel Dörfler 
1221b21d610eSAxel Dörfler 	uint32 columns;
1222b21d610eSAxel Dörfler 	uint32 rows;
1223b21d610eSAxel Dörfler 	BPrivate::get_workspaces_layout(&columns, &rows);
1224b21d610eSAxel Dörfler 
1225b21d610eSAxel Dörfler 	fRevertButton->SetEnabled(columns != fOriginalWorkspacesColumns
1226b21d610eSAxel Dörfler 		|| rows != fOriginalWorkspacesRows
12275de171daSAxel Dörfler 		|| fSelected != fOriginal);
1228a10cf76eSAxel Dörfler }
1229a10cf76eSAxel Dörfler 
1230a10cf76eSAxel Dörfler 
1231a10cf76eSAxel Dörfler void
12325de171daSAxel Dörfler ScreenWindow::_UpdateOriginal()
1233abc649b8SWaldemar Kornewald {
1234b21d610eSAxel Dörfler 	BPrivate::get_workspaces_layout(&fOriginalWorkspacesColumns,
1235b21d610eSAxel Dörfler 		&fOriginalWorkspacesRows);
1236b21d610eSAxel Dörfler 
1237abc649b8SWaldemar Kornewald 	fScreenMode.Get(fOriginal);
1238abc649b8SWaldemar Kornewald 	fScreenMode.UpdateOriginalModes();
1239abc649b8SWaldemar Kornewald }
1240abc649b8SWaldemar Kornewald 
1241abc649b8SWaldemar Kornewald 
1242abc649b8SWaldemar Kornewald void
124312966d04SAxel Dörfler ScreenWindow::_UpdateMonitor()
124412966d04SAxel Dörfler {
124512966d04SAxel Dörfler 	monitor_info info;
124612966d04SAxel Dörfler 	float diagonalInches;
124712966d04SAxel Dörfler 	status_t status = fScreenMode.GetMonitorInfo(info, &diagonalInches);
124855030977SAxel Dörfler 	if (status == B_OK) {
12491a8af605SAxel Dörfler 		char text[512];
125066ab1666SAxel Dörfler 		snprintf(text, sizeof(text), "%s%s%s %g\"", info.vendor,
125166ab1666SAxel Dörfler 			info.name[0] ? " " : "", info.name, diagonalInches);
125212966d04SAxel Dörfler 
125312966d04SAxel Dörfler 		fMonitorInfo->SetText(text);
125412966d04SAxel Dörfler 
125512966d04SAxel Dörfler 		if (fMonitorInfo->IsHidden())
125612966d04SAxel Dörfler 			fMonitorInfo->Show();
125755030977SAxel Dörfler 	} else {
125855030977SAxel Dörfler 		if (!fMonitorInfo->IsHidden())
125955030977SAxel Dörfler 			fMonitorInfo->Hide();
126055030977SAxel Dörfler 	}
1261af8f9c31SAxel Dörfler 
1262*8b46ee25SAdrien Destugues 	// Add info about the graphics device
1263*8b46ee25SAdrien Destugues 
1264*8b46ee25SAdrien Destugues 	accelerant_device_info deviceInfo;
1265*8b46ee25SAdrien Destugues 
1266*8b46ee25SAdrien Destugues 	if (fScreenMode.GetDeviceInfo(deviceInfo) == B_OK) {
1267*8b46ee25SAdrien Destugues 		BString deviceString;
1268*8b46ee25SAdrien Destugues 
1269*8b46ee25SAdrien Destugues 		if (deviceInfo.name[0] && deviceInfo.chipset[0]) {
1270*8b46ee25SAdrien Destugues 			deviceString.SetToFormat("%s (%s)", deviceInfo.name,
1271*8b46ee25SAdrien Destugues 				deviceInfo.chipset);
1272*8b46ee25SAdrien Destugues 		} else if (deviceInfo.name[0] || deviceInfo.chipset[0]) {
1273*8b46ee25SAdrien Destugues 			deviceString
1274*8b46ee25SAdrien Destugues 				= deviceInfo.name[0] ? deviceInfo.name : deviceInfo.chipset;
1275*8b46ee25SAdrien Destugues 		}
1276*8b46ee25SAdrien Destugues 
1277*8b46ee25SAdrien Destugues 		fDeviceInfo->SetText(deviceString);
1278*8b46ee25SAdrien Destugues 	}
1279*8b46ee25SAdrien Destugues 
1280*8b46ee25SAdrien Destugues 
128155030977SAxel Dörfler 	char text[512];
12821a8af605SAxel Dörfler 	size_t length = 0;
12831a8af605SAxel Dörfler 	text[0] = 0;
12841a8af605SAxel Dörfler 
128555030977SAxel Dörfler 	if (status == B_OK) {
1286af8f9c31SAxel Dörfler 		if (info.min_horizontal_frequency != 0
1287af8f9c31SAxel Dörfler 			&& info.min_vertical_frequency != 0
1288af8f9c31SAxel Dörfler 			&& info.max_pixel_clock != 0) {
12891a8af605SAxel Dörfler 			length = snprintf(text, sizeof(text),
1290c9e8f97aSAdrien Destugues 				B_TRANSLATE("Horizonal frequency:\t%lu - %lu kHz\n"
12919c1a9b92SAdrien Destugues 				"Vertical frequency:\t%lu - %lu Hz\n\n"
1292c9e8f97aSAdrien Destugues 				"Maximum pixel clock:\t%g MHz"),
12931a8af605SAxel Dörfler 				info.min_horizontal_frequency, info.max_horizontal_frequency,
12941a8af605SAxel Dörfler 				info.min_vertical_frequency, info.max_vertical_frequency,
12951a8af605SAxel Dörfler 				info.max_pixel_clock / 1000.0);
1296af8f9c31SAxel Dörfler 		}
12971a8af605SAxel Dörfler 		if (info.serial_number[0] && length < sizeof(text)) {
12981a8af605SAxel Dörfler 			length += snprintf(text + length, sizeof(text) - length,
1299c9e8f97aSAdrien Destugues 				B_TRANSLATE("%sSerial no.: %s"), length ? "\n\n" : "",
13001a8af605SAxel Dörfler 				info.serial_number);
13011a8af605SAxel Dörfler 			if (info.produced.week != 0 && info.produced.year != 0
13021a8af605SAxel Dörfler 				&& length < sizeof(text)) {
13031a8af605SAxel Dörfler 				length += snprintf(text + length, sizeof(text) - length,
13041a8af605SAxel Dörfler 					" (%u/%u)", info.produced.week, info.produced.year);
13051a8af605SAxel Dörfler 			}
13061a8af605SAxel Dörfler 		}
130755030977SAxel Dörfler 	}
130861c5c89bSAxel Dörfler 
13091a8af605SAxel Dörfler 	if (text[0])
13101a8af605SAxel Dörfler 		fMonitorView->SetToolTip(text);
131112966d04SAxel Dörfler }
131212966d04SAxel Dörfler 
131312966d04SAxel Dörfler 
131412966d04SAxel Dörfler void
13151fc4cb1fSAxel Dörfler ScreenWindow::_UpdateColorLabel()
13161fc4cb1fSAxel Dörfler {
13171fc4cb1fSAxel Dörfler 	BString string;
1318551c9f15SSiarzhuk Zharski 	string << fSelected.BitsPerPixel() << " " << B_TRANSLATE("bits/pixel");
13191fc4cb1fSAxel Dörfler 	fColorsMenu->Superitem()->SetLabel(string.String());
13201fc4cb1fSAxel Dörfler }
13211fc4cb1fSAxel Dörfler 
13221fc4cb1fSAxel Dörfler 
13231fc4cb1fSAxel Dörfler void
13245de171daSAxel Dörfler ScreenWindow::_Apply()
1325a10cf76eSAxel Dörfler {
1326abc649b8SWaldemar Kornewald 	// make checkpoint, so we can undo these changes
132761c5c89bSAxel Dörfler 	fUndoScreenMode.UpdateOriginalModes();
132861c5c89bSAxel Dörfler 
132907184a9eSAxel Dörfler 	status_t status = fScreenMode.Set(fSelected);
133007184a9eSAxel Dörfler 	if (status == B_OK) {
1331abc649b8SWaldemar Kornewald 		// use the mode that has eventually been set and
1332abc649b8SWaldemar Kornewald 		// thus we know to be working; it can differ from
1333abc649b8SWaldemar Kornewald 		// the mode selected by user due to hardware limitation
1334abc649b8SWaldemar Kornewald 		display_mode newMode;
1335abc649b8SWaldemar Kornewald 		BScreen screen(this);
1336abc649b8SWaldemar Kornewald 		screen.GetMode(&newMode);
1337abc649b8SWaldemar Kornewald 
1338abc649b8SWaldemar Kornewald 		if (fAllWorkspacesItem->IsMarked()) {
1339abc649b8SWaldemar Kornewald 			int32 originatingWorkspace = current_workspace();
1340abc649b8SWaldemar Kornewald 			for (int32 i = 0; i < count_workspaces(); i++) {
1341abc649b8SWaldemar Kornewald 				if (i != originatingWorkspace)
1342abc649b8SWaldemar Kornewald 					screen.SetMode(i, &newMode, true);
1343abc649b8SWaldemar Kornewald 			}
1344199893c3SAxel Dörfler 			fBootWorkspaceApplied = true;
1345199893c3SAxel Dörfler 		} else {
1346199893c3SAxel Dörfler 			if (current_workspace() == 0)
1347199893c3SAxel Dörfler 				fBootWorkspaceApplied = true;
1348abc649b8SWaldemar Kornewald 		}
1349abc649b8SWaldemar Kornewald 
1350a10cf76eSAxel Dörfler 		fActive = fSelected;
1351a10cf76eSAxel Dörfler 
1352abc649b8SWaldemar Kornewald 		// TODO: only show alert when this is an unknown mode
1353a10cf76eSAxel Dörfler 		BWindow* window = new AlertWindow(this);
1354a10cf76eSAxel Dörfler 		window->Show();
135507184a9eSAxel Dörfler 	} else {
135607184a9eSAxel Dörfler 		char message[256];
135707184a9eSAxel Dörfler 		snprintf(message, sizeof(message),
1358c9e8f97aSAdrien Destugues 			B_TRANSLATE("The screen mode could not be set:\n\t%s\n"),
1359c9e8f97aSAdrien Destugues 			screen_errors(status));
1360551c9f15SSiarzhuk Zharski 		BAlert* alert = new BAlert(B_TRANSLATE("Warning"), message,
1361c9e8f97aSAdrien Destugues 			B_TRANSLATE("OK"), NULL, NULL,
136207184a9eSAxel Dörfler 			B_WIDTH_AS_USUAL, B_WARNING_ALERT);
1363aed35104SHumdinger 		alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE);
136407184a9eSAxel Dörfler 		alert->Go();
1365a10cf76eSAxel Dörfler 	}
136607184a9eSAxel Dörfler }
1367