xref: /haiku/src/preferences/screen/ScreenWindow.cpp (revision 6048f54145df1c26c3590e7a1613f7cda70eee81)
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>
22b21d610eSAxel Dörfler #include <string.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 
224c9e8f97aSAdrien Destugues 	fMonitorView = new MonitorView(BRect(0.0, 0.0, 80.0, 80.0),
225551c9f15SSiarzhuk Zharski 		"monitor", screen.Frame().IntegerWidth() + 1,
226c9e8f97aSAdrien Destugues 		screen.Frame().IntegerHeight() + 1);
227b21d610eSAxel Dörfler 	screenBox->AddChild(fMonitorView);
2285a78744bSAxel Dörfler 
229e1c88201SJohn Scipione 	BStringView* workspaces = new BStringView("workspaces",
230e1c88201SJohn Scipione 		B_TRANSLATE("Workspaces"));
231e1c88201SJohn Scipione 	workspaces->SetAlignment(B_ALIGN_CENTER);
232e1c88201SJohn Scipione 
233c9e8f97aSAdrien Destugues 	fColumnsControl = new BTextControl(B_TRANSLATE("Columns:"), "0",
234b21d610eSAxel Dörfler 		new BMessage(kMsgWorkspaceColumnsChanged));
235e1c88201SJohn Scipione 	fColumnsControl->SetAlignment(B_ALIGN_RIGHT, B_ALIGN_LEFT);
236c9e8f97aSAdrien Destugues 	fRowsControl = new BTextControl(B_TRANSLATE("Rows:"), "0",
237b21d610eSAxel Dörfler 		new BMessage(kMsgWorkspaceRowsChanged));
238e1c88201SJohn Scipione 	fRowsControl->SetAlignment(B_ALIGN_RIGHT, B_ALIGN_LEFT);
239b21d610eSAxel Dörfler 
240e1c88201SJohn Scipione 	float tiny = be_control_look->DefaultItemSpacing() / 4;
241e1c88201SJohn Scipione 	screenBox->AddChild(BLayoutBuilder::Group<>()
242e1c88201SJohn Scipione 		.AddGroup(B_VERTICAL, B_USE_SMALL_SPACING)
243e1c88201SJohn Scipione 			.Add(workspaces)
244e1c88201SJohn Scipione 			.AddGrid(0.0, tiny)
245e1c88201SJohn Scipione 				// columns
246e1c88201SJohn Scipione 				.Add(fColumnsControl->CreateLabelLayoutItem(), 0, 0)
247e1c88201SJohn Scipione 				.Add(BSpaceLayoutItem::CreateHorizontalStrut(
248e1c88201SJohn Scipione 					B_USE_SMALL_SPACING), 1, 0)
249e1c88201SJohn Scipione 				.Add(fColumnsControl->CreateTextViewLayoutItem(), 2, 0)
250e1c88201SJohn Scipione 				.Add(BSpaceLayoutItem::CreateHorizontalStrut(tiny), 3, 0)
251e1c88201SJohn Scipione 				.Add(_CreateColumnRowButton(true, false), 4, 0)
252e1c88201SJohn Scipione 				.Add(_CreateColumnRowButton(true, true), 5, 0)
253e1c88201SJohn Scipione 				// rows
254e1c88201SJohn Scipione 				.Add(fRowsControl->CreateLabelLayoutItem(), 0, 1)
255e1c88201SJohn Scipione 				.Add(BSpaceLayoutItem::CreateHorizontalStrut(
256e1c88201SJohn Scipione 					B_USE_SMALL_SPACING), 1, 1)
257e1c88201SJohn Scipione 				.Add(fRowsControl->CreateTextViewLayoutItem(), 2, 1)
258e1c88201SJohn Scipione 				.Add(BSpaceLayoutItem::CreateHorizontalStrut(tiny), 3, 1)
259e1c88201SJohn Scipione 				.Add(_CreateColumnRowButton(false, false), 4, 1)
260e1c88201SJohn Scipione 				.Add(_CreateColumnRowButton(false, true), 5, 1)
261b21d610eSAxel Dörfler 				.End()
26225fd5c7bSAlex Wilson 			.End()
26325fd5c7bSAlex Wilson 		.View());
264b21d610eSAxel Dörfler 
265b21d610eSAxel Dörfler 	fBackgroundsButton = new BButton("BackgroundsButton",
266c9e8f97aSAdrien Destugues 		B_TRANSLATE("Set background" B_UTF8_ELLIPSIS),
267b21d610eSAxel Dörfler 		new BMessage(BUTTON_LAUNCH_BACKGROUNDS_MSG));
268b21d610eSAxel Dörfler 	fBackgroundsButton->SetFontSize(be_plain_font->Size() * 0.9);
269b21d610eSAxel Dörfler 	screenBox->AddChild(fBackgroundsButton);
270a10cf76eSAxel Dörfler 
271a10cf76eSAxel Dörfler 	// box on the right with screen resolution, etc.
272a10cf76eSAxel Dörfler 
273b21d610eSAxel Dörfler 	BBox* controlsBox = new BBox("controls box");
274b21d610eSAxel Dörfler 	controlsBox->SetLabel(workspaceMenuField);
275*6048f541SJohn Scipione 	BGroupView* outerControlsView = new BGroupView(B_VERTICAL);
276*6048f541SJohn Scipione 	outerControlsView->GroupLayout()->SetInsets(B_USE_DEFAULT_SPACING,
277*6048f541SJohn Scipione 		B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING);
278b21d610eSAxel Dörfler 	controlsBox->AddChild(outerControlsView);
279a10cf76eSAxel Dörfler 
280551c9f15SSiarzhuk Zharski 	fResolutionMenu = new BPopUpMenu("resolution", true, true);
281a10cf76eSAxel Dörfler 
28266ab1666SAxel Dörfler 	uint16 maxWidth = 0;
28366ab1666SAxel Dörfler 	uint16 maxHeight = 0;
28466ab1666SAxel Dörfler 	uint16 previousWidth = 0;
28566ab1666SAxel Dörfler 	uint16 previousHeight = 0;
286a10cf76eSAxel Dörfler 	for (int32 i = 0; i < fScreenMode.CountModes(); i++) {
287a10cf76eSAxel Dörfler 		screen_mode mode = fScreenMode.ModeAt(i);
288a10cf76eSAxel Dörfler 
289a10cf76eSAxel Dörfler 		if (mode.width == previousWidth && mode.height == previousHeight)
290a10cf76eSAxel Dörfler 			continue;
291a10cf76eSAxel Dörfler 
292a10cf76eSAxel Dörfler 		previousWidth = mode.width;
293a10cf76eSAxel Dörfler 		previousHeight = mode.height;
29466ab1666SAxel Dörfler 		if (maxWidth < mode.width)
29566ab1666SAxel Dörfler 			maxWidth = mode.width;
29666ab1666SAxel Dörfler 		if (maxHeight < mode.height)
29766ab1666SAxel Dörfler 			maxHeight = mode.height;
298a10cf76eSAxel Dörfler 
299a10cf76eSAxel Dörfler 		BMessage* message = new BMessage(POP_RESOLUTION_MSG);
300a10cf76eSAxel Dörfler 		message->AddInt32("width", mode.width);
301a10cf76eSAxel Dörfler 		message->AddInt32("height", mode.height);
302a10cf76eSAxel Dörfler 
303a10cf76eSAxel Dörfler 		BString name;
304a10cf76eSAxel Dörfler 		name << mode.width << " x " << mode.height;
305a10cf76eSAxel Dörfler 
306a10cf76eSAxel Dörfler 		fResolutionMenu->AddItem(new BMenuItem(name.String(), message));
307a10cf76eSAxel Dörfler 	}
308a10cf76eSAxel Dörfler 
30966ab1666SAxel Dörfler 	fMonitorView->SetMaxResolution(maxWidth, maxHeight);
31066ab1666SAxel Dörfler 
311c9e8f97aSAdrien Destugues 	fResolutionField = new BMenuField("ResolutionMenu",
31210dfe897SAxel Dörfler 		B_TRANSLATE("Resolution:"), fResolutionMenu);
313*6048f541SJohn Scipione 	fResolutionField->SetAlignment(B_ALIGN_RIGHT);
314a10cf76eSAxel Dörfler 
315551c9f15SSiarzhuk Zharski 	fColorsMenu = new BPopUpMenu("colors", true, false);
316a10cf76eSAxel Dörfler 
317a10cf76eSAxel Dörfler 	for (int32 i = 0; i < kColorSpaceCount; i++) {
3181fc4cb1fSAxel Dörfler 		if ((fSupportedColorSpaces & (1 << i)) == 0)
3191fc4cb1fSAxel Dörfler 			continue;
3201fc4cb1fSAxel Dörfler 
321a10cf76eSAxel Dörfler 		BMessage* message = new BMessage(POP_COLORS_MSG);
322a10cf76eSAxel Dörfler 		message->AddInt32("bits_per_pixel", kColorSpaces[i].bits_per_pixel);
323a10cf76eSAxel Dörfler 		message->AddInt32("space", kColorSpaces[i].space);
324a10cf76eSAxel Dörfler 
3251fc4cb1fSAxel Dörfler 		BMenuItem* item = new BMenuItem(kColorSpaces[i].label, message);
3261fc4cb1fSAxel Dörfler 		if (kColorSpaces[i].space == screen.ColorSpace())
3271fc4cb1fSAxel Dörfler 			fUserSelectedColorSpace = item;
3281fc4cb1fSAxel Dörfler 
3291fc4cb1fSAxel Dörfler 		fColorsMenu->AddItem(item);
330a10cf76eSAxel Dörfler 	}
331a10cf76eSAxel Dörfler 
332c9e8f97aSAdrien Destugues 	fColorsField = new BMenuField("ColorsMenu", B_TRANSLATE("Colors:"),
33310dfe897SAxel Dörfler 		fColorsMenu);
334*6048f541SJohn Scipione 	fColorsField->SetAlignment(B_ALIGN_RIGHT);
335a10cf76eSAxel Dörfler 
336551c9f15SSiarzhuk Zharski 	fRefreshMenu = new BPopUpMenu("refresh rate", true, true);
337a10cf76eSAxel Dörfler 
33829e8a73aSAxel Dörfler 	float min, max;
339ec495b30SRene Gollent 	if (fScreenMode.GetRefreshLimits(fActive, min, max) != B_OK) {
340ec495b30SRene Gollent 		// if we couldn't obtain the refresh limits, reset to the default
341ec495b30SRene Gollent 		// range. Constraints from detected monitors will fine-tune this
342ec495b30SRene Gollent 		// later.
343ec495b30SRene Gollent 		min = kRefreshRates[0];
344ec495b30SRene Gollent 		max = kRefreshRates[kRefreshRateCount - 1];
345ec495b30SRene Gollent 	}
346ec495b30SRene Gollent 
347ec495b30SRene Gollent 	if (min == max) {
34829e8a73aSAxel Dörfler 		// This is a special case for drivers that only support a single
34929e8a73aSAxel Dörfler 		// frequency, like the VESA driver
35029e8a73aSAxel Dörfler 		BString name;
3517e44de36SRene Gollent 		refresh_rate_to_string(min, name);
352cf076964SRene Gollent 		BMessage *message = new BMessage(POP_REFRESH_MSG);
353cf076964SRene Gollent 		message->AddFloat("refresh", min);
354cf076964SRene Gollent 		BMenuItem *item = new BMenuItem(name.String(), message);
3550efb8b66SJerome Duval 		fRefreshMenu->AddItem(item);
35629e8a73aSAxel Dörfler 		item->SetEnabled(false);
35729e8a73aSAxel Dörfler 	} else {
35870a2b1b5SAxel Dörfler 		monitor_info info;
35970a2b1b5SAxel Dörfler 		if (fScreenMode.GetMonitorInfo(info) == B_OK) {
36070a2b1b5SAxel Dörfler 			min = max_c(info.min_vertical_frequency, min);
36170a2b1b5SAxel Dörfler 			max = min_c(info.max_vertical_frequency, max);
36270a2b1b5SAxel Dörfler 		}
36370a2b1b5SAxel Dörfler 
364a10cf76eSAxel Dörfler 		for (int32 i = 0; i < kRefreshRateCount; ++i) {
36570a2b1b5SAxel Dörfler 			if (kRefreshRates[i] < min || kRefreshRates[i] > max)
36670a2b1b5SAxel Dörfler 				continue;
36770a2b1b5SAxel Dörfler 
368a10cf76eSAxel Dörfler 			BString name;
369551c9f15SSiarzhuk Zharski 			name << kRefreshRates[i] << " " << B_TRANSLATE("Hz");
370a10cf76eSAxel Dörfler 
3710efb8b66SJerome Duval 			BMessage *message = new BMessage(POP_REFRESH_MSG);
372a10cf76eSAxel Dörfler 			message->AddFloat("refresh", kRefreshRates[i]);
373a10cf76eSAxel Dörfler 
374a10cf76eSAxel Dörfler 			fRefreshMenu->AddItem(new BMenuItem(name.String(), message));
375a10cf76eSAxel Dörfler 		}
376a10cf76eSAxel Dörfler 
377c9e8f97aSAdrien Destugues 		fOtherRefresh = new BMenuItem(B_TRANSLATE("Other" B_UTF8_ELLIPSIS),
3780efb8b66SJerome Duval 			new BMessage(POP_OTHER_REFRESH_MSG));
379a10cf76eSAxel Dörfler 		fRefreshMenu->AddItem(fOtherRefresh);
38029e8a73aSAxel Dörfler 	}
381a10cf76eSAxel Dörfler 
382c9e8f97aSAdrien Destugues 	fRefreshField = new BMenuField("RefreshMenu", B_TRANSLATE("Refresh rate:"),
38310dfe897SAxel Dörfler 		fRefreshMenu);
384*6048f541SJohn Scipione 	fRefreshField->SetAlignment(B_ALIGN_RIGHT);
385b21d610eSAxel Dörfler 
38612580984SAxel Dörfler 	if (_IsVesa())
38712580984SAxel Dörfler 		fRefreshField->Hide();
388a10cf76eSAxel Dörfler 
389a10cf76eSAxel Dörfler 	// enlarged area for multi-monitor settings
390a10cf76eSAxel Dörfler 	{
391a10cf76eSAxel Dörfler 		bool dummy;
392a10cf76eSAxel Dörfler 		uint32 dummy32;
393a10cf76eSAxel Dörfler 		bool multiMonSupport;
394a10cf76eSAxel Dörfler 		bool useLaptopPanelSupport;
395a10cf76eSAxel Dörfler 		bool tvStandardSupport;
396a10cf76eSAxel Dörfler 
397a10cf76eSAxel Dörfler 		multiMonSupport = TestMultiMonSupport(&screen) == B_OK;
398a10cf76eSAxel Dörfler 		useLaptopPanelSupport = GetUseLaptopPanel(&screen, &dummy) == B_OK;
399a10cf76eSAxel Dörfler 		tvStandardSupport = GetTVStandard(&screen, &dummy32) == B_OK;
400a10cf76eSAxel Dörfler 
401a10cf76eSAxel Dörfler 		// even if there is no support, we still create all controls
402a10cf76eSAxel Dörfler 		// to make sure we don't access NULL pointers later on
403a10cf76eSAxel Dörfler 
404551c9f15SSiarzhuk Zharski 		fCombineMenu = new BPopUpMenu("CombineDisplays",
405c9e8f97aSAdrien Destugues 			true, true);
406a10cf76eSAxel Dörfler 
407a10cf76eSAxel Dörfler 		for (int32 i = 0; i < kCombineModeCount; i++) {
4080efb8b66SJerome Duval 			BMessage *message = new BMessage(POP_COMBINE_DISPLAYS_MSG);
409a10cf76eSAxel Dörfler 			message->AddInt32("mode", kCombineModes[i].mode);
410a10cf76eSAxel Dörfler 
411d1516993SAxel Dörfler 			fCombineMenu->AddItem(new BMenuItem(kCombineModes[i].name,
412d1516993SAxel Dörfler 				message));
413a10cf76eSAxel Dörfler 		}
414a10cf76eSAxel Dörfler 
415b21d610eSAxel Dörfler 		fCombineField = new BMenuField("CombineMenu",
41610dfe897SAxel Dörfler 			B_TRANSLATE("Combine displays:"), fCombineMenu);
417*6048f541SJohn Scipione 		fCombineField->SetAlignment(B_ALIGN_RIGHT);
418a10cf76eSAxel Dörfler 
419a10cf76eSAxel Dörfler 		if (!multiMonSupport)
420df3f5bacSStephan Aßmus 			fCombineField->Hide();
421a10cf76eSAxel Dörfler 
422551c9f15SSiarzhuk Zharski 		fSwapDisplaysMenu = new BPopUpMenu("SwapDisplays",
423c9e8f97aSAdrien Destugues 			true, true);
424a10cf76eSAxel Dörfler 
425a10cf76eSAxel Dörfler 		// !order is important - we rely that boolean value == idx
4260efb8b66SJerome Duval 		BMessage *message = new BMessage(POP_SWAP_DISPLAYS_MSG);
427a10cf76eSAxel Dörfler 		message->AddBool("swap", false);
428c9e8f97aSAdrien Destugues 		fSwapDisplaysMenu->AddItem(new BMenuItem(B_TRANSLATE("no"), message));
429a10cf76eSAxel Dörfler 
430a10cf76eSAxel Dörfler 		message = new BMessage(POP_SWAP_DISPLAYS_MSG);
431a10cf76eSAxel Dörfler 		message->AddBool("swap", true);
432c9e8f97aSAdrien Destugues 		fSwapDisplaysMenu->AddItem(new BMenuItem(B_TRANSLATE("yes"), message));
433a10cf76eSAxel Dörfler 
434c9e8f97aSAdrien Destugues 		fSwapDisplaysField = new BMenuField("SwapMenu",
43510dfe897SAxel Dörfler 			B_TRANSLATE("Swap displays:"), fSwapDisplaysMenu);
436*6048f541SJohn Scipione 		fSwapDisplaysField->SetAlignment(B_ALIGN_RIGHT);
437a10cf76eSAxel Dörfler 
438a10cf76eSAxel Dörfler 		if (!multiMonSupport)
439df3f5bacSStephan Aßmus 			fSwapDisplaysField->Hide();
440a10cf76eSAxel Dörfler 
441551c9f15SSiarzhuk Zharski 		fUseLaptopPanelMenu = new BPopUpMenu("UseLaptopPanel",
442c9e8f97aSAdrien Destugues 			true, true);
443a10cf76eSAxel Dörfler 
444a10cf76eSAxel Dörfler 		// !order is important - we rely that boolean value == idx
445a10cf76eSAxel Dörfler 		message = new BMessage(POP_USE_LAPTOP_PANEL_MSG);
446a10cf76eSAxel Dörfler 		message->AddBool("use", false);
447c9e8f97aSAdrien Destugues 		fUseLaptopPanelMenu->AddItem(new BMenuItem(B_TRANSLATE("if needed"),
448c9e8f97aSAdrien Destugues 			message));
449a10cf76eSAxel Dörfler 
450a10cf76eSAxel Dörfler 		message = new BMessage(POP_USE_LAPTOP_PANEL_MSG);
451a10cf76eSAxel Dörfler 		message->AddBool("use", true);
452c9e8f97aSAdrien Destugues 		fUseLaptopPanelMenu->AddItem(new BMenuItem(B_TRANSLATE("always"),
453c9e8f97aSAdrien Destugues 			message));
454a10cf76eSAxel Dörfler 
455b21d610eSAxel Dörfler 		fUseLaptopPanelField = new BMenuField("UseLaptopPanel",
45610dfe897SAxel Dörfler 			B_TRANSLATE("Use laptop panel:"), fUseLaptopPanelMenu);
457*6048f541SJohn Scipione 		fUseLaptopPanelField->SetAlignment(B_ALIGN_RIGHT);
458a10cf76eSAxel Dörfler 
459a10cf76eSAxel Dörfler 		if (!useLaptopPanelSupport)
460df3f5bacSStephan Aßmus 			fUseLaptopPanelField->Hide();
461a10cf76eSAxel Dörfler 
462551c9f15SSiarzhuk Zharski 		fTVStandardMenu = new BPopUpMenu("TVStandard", true, true);
463a10cf76eSAxel Dörfler 
464a10cf76eSAxel Dörfler 		// arbitrary limit
465a10cf76eSAxel Dörfler 		uint32 i;
466a10cf76eSAxel Dörfler 		for (i = 0; i < 100; ++i) {
467a10cf76eSAxel Dörfler 			uint32 mode;
468a10cf76eSAxel Dörfler 			if (GetNthSupportedTVStandard(&screen, i, &mode) != B_OK)
469a10cf76eSAxel Dörfler 				break;
470a10cf76eSAxel Dörfler 
471a10cf76eSAxel Dörfler 			BString name = tv_standard_to_string(mode);
472a10cf76eSAxel Dörfler 
473a10cf76eSAxel Dörfler 			message = new BMessage(POP_TV_STANDARD_MSG);
474a10cf76eSAxel Dörfler 			message->AddInt32("tv_standard", mode);
475a10cf76eSAxel Dörfler 
476a10cf76eSAxel Dörfler 			fTVStandardMenu->AddItem(new BMenuItem(name.String(), message));
477a10cf76eSAxel Dörfler 		}
478a10cf76eSAxel Dörfler 
479c9e8f97aSAdrien Destugues 		fTVStandardField = new BMenuField("tv standard",
48010dfe897SAxel Dörfler 			B_TRANSLATE("Video format:"), fTVStandardMenu);
481df3f5bacSStephan Aßmus 		fTVStandardField->SetAlignment(B_ALIGN_RIGHT);
482a10cf76eSAxel Dörfler 
483b21d610eSAxel Dörfler 		if (!tvStandardSupport || i == 0)
484df3f5bacSStephan Aßmus 			fTVStandardField->Hide();
485a10cf76eSAxel Dörfler 	}
486a10cf76eSAxel Dörfler 
48725fd5c7bSAlex Wilson 	BLayoutBuilder::Group<>(outerControlsView)
488*6048f541SJohn Scipione 		.AddGrid(B_USE_DEFAULT_SPACING, B_USE_SMALL_SPACING)
489*6048f541SJohn Scipione 			.Add(fResolutionField->CreateLabelLayoutItem(), 0, 0)
490*6048f541SJohn Scipione 			.Add(fResolutionField->CreateMenuBarLayoutItem(), 1, 0)
491*6048f541SJohn Scipione 			.Add(fColorsField->CreateLabelLayoutItem(), 0, 1)
492*6048f541SJohn Scipione 			.Add(fColorsField->CreateMenuBarLayoutItem(), 1, 1)
493*6048f541SJohn Scipione 			.Add(fRefreshField->CreateLabelLayoutItem(), 0, 2)
494*6048f541SJohn Scipione 			.Add(fRefreshField->CreateMenuBarLayoutItem(), 1, 2)
495*6048f541SJohn Scipione 			.Add(fCombineField->CreateLabelLayoutItem(), 0, 3)
496*6048f541SJohn Scipione 			.Add(fCombineField->CreateMenuBarLayoutItem(), 1, 3)
497*6048f541SJohn Scipione 			.Add(fSwapDisplaysField->CreateLabelLayoutItem(), 0, 4)
498*6048f541SJohn Scipione 			.Add(fSwapDisplaysField->CreateMenuBarLayoutItem(), 1, 4)
499*6048f541SJohn Scipione 			.Add(fUseLaptopPanelField->CreateLabelLayoutItem(), 0, 5)
500*6048f541SJohn Scipione 			.Add(fUseLaptopPanelField->CreateMenuBarLayoutItem(), 1, 5)
501*6048f541SJohn Scipione 			.Add(fTVStandardField->CreateLabelLayoutItem(), 0, 6)
502*6048f541SJohn Scipione 			.Add(fTVStandardField->CreateMenuBarLayoutItem(), 1, 6)
50325fd5c7bSAlex Wilson 		.End();
504df3f5bacSStephan Aßmus 
505abc649b8SWaldemar Kornewald 	// TODO: we don't support getting the screen's preferred settings
506abc649b8SWaldemar Kornewald 	/* fDefaultsButton = new BButton(buttonRect, "DefaultsButton", "Defaults",
507b21d610eSAxel Dörfler 		new BMessage(BUTTON_DEFAULTS_MSG));*/
508a10cf76eSAxel Dörfler 
509c9e8f97aSAdrien Destugues 	fApplyButton = new BButton("ApplyButton", B_TRANSLATE("Apply"),
510df3f5bacSStephan Aßmus 		new BMessage(BUTTON_APPLY_MSG));
511df3f5bacSStephan Aßmus 	fApplyButton->SetEnabled(false);
51225fd5c7bSAlex Wilson 	BLayoutBuilder::Group<>(outerControlsView)
513b21d610eSAxel Dörfler 		.AddGlue()
51425fd5c7bSAlex Wilson 			.AddGroup(B_HORIZONTAL)
51525fd5c7bSAlex Wilson 			.AddGlue()
51625fd5c7bSAlex Wilson 			.Add(fApplyButton);
517b21d610eSAxel Dörfler 
518c9e8f97aSAdrien Destugues 	fRevertButton = new BButton("RevertButton", B_TRANSLATE("Revert"),
519b21d610eSAxel Dörfler 		new BMessage(BUTTON_REVERT_MSG));
520b21d610eSAxel Dörfler 	fRevertButton->SetEnabled(false);
521b21d610eSAxel Dörfler 
5224666484fSJohn Scipione 	BLayoutBuilder::Group<>(this, B_VERTICAL, B_USE_DEFAULT_SPACING)
5234666484fSJohn Scipione 		.AddGroup(B_HORIZONTAL)
52483cc66b3SJohn Scipione 			.AddGroup(B_VERTICAL, 0)
52583cc66b3SJohn Scipione 				.AddStrut(floorf(controlsBox->TopBorderOffset()) - 1)
526b21d610eSAxel Dörfler 				.Add(screenBox)
52783cc66b3SJohn Scipione 				.End()
528b21d610eSAxel Dörfler 			.Add(controlsBox)
529b21d610eSAxel Dörfler 			.End()
5304666484fSJohn Scipione 		.AddGroup(B_HORIZONTAL, B_USE_DEFAULT_SPACING)
531b21d610eSAxel Dörfler 			.Add(fRevertButton)
5324666484fSJohn Scipione 			.AddGlue()
5334666484fSJohn Scipione 			.End()
5344666484fSJohn Scipione 		.SetInsets(B_USE_DEFAULT_SPACING);
535b21d610eSAxel Dörfler 
5365de171daSAxel Dörfler 	_UpdateControls();
53712966d04SAxel Dörfler 	_UpdateMonitor();
538a10cf76eSAxel Dörfler }
539a10cf76eSAxel Dörfler 
540a10cf76eSAxel Dörfler 
541a10cf76eSAxel Dörfler ScreenWindow::~ScreenWindow()
542a10cf76eSAxel Dörfler {
543a10cf76eSAxel Dörfler 	delete fSettings;
544a10cf76eSAxel Dörfler }
545a10cf76eSAxel Dörfler 
546a10cf76eSAxel Dörfler 
547a10cf76eSAxel Dörfler bool
548a10cf76eSAxel Dörfler ScreenWindow::QuitRequested()
549a10cf76eSAxel Dörfler {
550a10cf76eSAxel Dörfler 	fSettings->SetWindowFrame(Frame());
551199893c3SAxel Dörfler 
552199893c3SAxel Dörfler 	// Write mode of workspace 0 (the boot workspace) to the vesa settings file
553199893c3SAxel Dörfler 	screen_mode vesaMode;
554199893c3SAxel Dörfler 	if (fBootWorkspaceApplied && fScreenMode.Get(vesaMode, 0) == B_OK) {
555199893c3SAxel Dörfler 		status_t status = _WriteVesaModeFile(vesaMode);
55612580984SAxel Dörfler 		if (status < B_OK) {
557c9e8f97aSAdrien Destugues 			BString warning = B_TRANSLATE("Could not write VESA mode settings"
558c9e8f97aSAdrien Destugues 				" file:\n\t");
55912580984SAxel Dörfler 			warning << strerror(status);
560aed35104SHumdinger 			BAlert* alert = new BAlert(B_TRANSLATE("Warning"),
561aed35104SHumdinger 				warning.String(), B_TRANSLATE("OK"), NULL,
562aed35104SHumdinger 				NULL, B_WIDTH_AS_USUAL, B_WARNING_ALERT);
563aed35104SHumdinger 			alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE);
564aed35104SHumdinger 			alert->Go();
56512580984SAxel Dörfler 		}
56612580984SAxel Dörfler 	}
56712580984SAxel Dörfler 
568a10cf76eSAxel Dörfler 	be_app->PostMessage(B_QUIT_REQUESTED);
569a10cf76eSAxel Dörfler 
570a10cf76eSAxel Dörfler 	return BWindow::QuitRequested();
571a10cf76eSAxel Dörfler }
572a10cf76eSAxel Dörfler 
573a10cf76eSAxel Dörfler 
5745de171daSAxel Dörfler /*!	Update resolution list according to combine mode
5751fc4cb1fSAxel Dörfler 	(some resolutions may not be combinable due to memory restrictions).
576a10cf76eSAxel Dörfler */
577a10cf76eSAxel Dörfler void
5785de171daSAxel Dörfler ScreenWindow::_CheckResolutionMenu()
579a10cf76eSAxel Dörfler {
580a10cf76eSAxel Dörfler 	for (int32 i = 0; i < fResolutionMenu->CountItems(); i++)
581a10cf76eSAxel Dörfler 		fResolutionMenu->ItemAt(i)->SetEnabled(false);
582a10cf76eSAxel Dörfler 
583a10cf76eSAxel Dörfler 	for (int32 i = 0; i < fScreenMode.CountModes(); i++) {
584a10cf76eSAxel Dörfler 		screen_mode mode = fScreenMode.ModeAt(i);
585a10cf76eSAxel Dörfler 		if (mode.combine != fSelected.combine)
586a10cf76eSAxel Dörfler 			continue;
587a10cf76eSAxel Dörfler 
588a10cf76eSAxel Dörfler 		BString name;
589a10cf76eSAxel Dörfler 		name << mode.width << " x " << mode.height;
590a10cf76eSAxel Dörfler 
591a10cf76eSAxel Dörfler 		BMenuItem *item = fResolutionMenu->FindItem(name.String());
592a10cf76eSAxel Dörfler 		if (item != NULL)
593a10cf76eSAxel Dörfler 			item->SetEnabled(true);
594a10cf76eSAxel Dörfler 	}
595a10cf76eSAxel Dörfler }
596a10cf76eSAxel Dörfler 
597a10cf76eSAxel Dörfler 
5985de171daSAxel Dörfler /*!	Update color and refresh options according to current mode
5995de171daSAxel Dörfler 	(a color space is made active if there is any mode with
6005de171daSAxel Dörfler 	given resolution and this colour space; same applies for
6015de171daSAxel Dörfler 	refresh rate, though "Other…" is always possible)
602a10cf76eSAxel Dörfler */
603a10cf76eSAxel Dörfler void
6045de171daSAxel Dörfler ScreenWindow::_CheckColorMenu()
605a10cf76eSAxel Dörfler {
6061fc4cb1fSAxel Dörfler 	int32 supportsAnything = false;
6071fc4cb1fSAxel Dörfler 	int32 index = 0;
6081fc4cb1fSAxel Dörfler 
609a10cf76eSAxel Dörfler 	for (int32 i = 0; i < kColorSpaceCount; i++) {
6101fc4cb1fSAxel Dörfler 		if ((fSupportedColorSpaces & (1 << i)) == 0)
6111fc4cb1fSAxel Dörfler 			continue;
6121fc4cb1fSAxel Dörfler 
613a10cf76eSAxel Dörfler 		bool supported = false;
614a10cf76eSAxel Dörfler 
615a10cf76eSAxel Dörfler 		for (int32 j = 0; j < fScreenMode.CountModes(); j++) {
616a10cf76eSAxel Dörfler 			screen_mode mode = fScreenMode.ModeAt(j);
617a10cf76eSAxel Dörfler 
618a10cf76eSAxel Dörfler 			if (fSelected.width == mode.width
619a10cf76eSAxel Dörfler 				&& fSelected.height == mode.height
6201fc4cb1fSAxel Dörfler 				&& kColorSpaces[i].space == mode.space
621a10cf76eSAxel Dörfler 				&& fSelected.combine == mode.combine) {
6221fc4cb1fSAxel Dörfler 				supportsAnything = true;
623a10cf76eSAxel Dörfler 				supported = true;
624a10cf76eSAxel Dörfler 				break;
625a10cf76eSAxel Dörfler 			}
626a10cf76eSAxel Dörfler 		}
627a10cf76eSAxel Dörfler 
6281fc4cb1fSAxel Dörfler 		BMenuItem* item = fColorsMenu->ItemAt(index++);
629a10cf76eSAxel Dörfler 		if (item)
630a10cf76eSAxel Dörfler 			item->SetEnabled(supported);
631a10cf76eSAxel Dörfler 	}
6321fc4cb1fSAxel Dörfler 
6331fc4cb1fSAxel Dörfler 	fColorsField->SetEnabled(supportsAnything);
6341fc4cb1fSAxel Dörfler 
6351fc4cb1fSAxel Dörfler 	if (!supportsAnything)
6361fc4cb1fSAxel Dörfler 		return;
6371fc4cb1fSAxel Dörfler 
6381fc4cb1fSAxel Dörfler 	// Make sure a valid item is selected
6391fc4cb1fSAxel Dörfler 
6401fc4cb1fSAxel Dörfler 	BMenuItem* item = fColorsMenu->FindMarked();
6411fc4cb1fSAxel Dörfler 	bool changed = false;
6421fc4cb1fSAxel Dörfler 
6431fc4cb1fSAxel Dörfler 	if (item != fUserSelectedColorSpace) {
6441fc4cb1fSAxel Dörfler 		if (fUserSelectedColorSpace != NULL
6451fc4cb1fSAxel Dörfler 			&& fUserSelectedColorSpace->IsEnabled()) {
6461fc4cb1fSAxel Dörfler 			fUserSelectedColorSpace->SetMarked(true);
6471fc4cb1fSAxel Dörfler 			item = fUserSelectedColorSpace;
6481fc4cb1fSAxel Dörfler 			changed = true;
6491fc4cb1fSAxel Dörfler 		}
6501fc4cb1fSAxel Dörfler 	}
6511fc4cb1fSAxel Dörfler 	if (item != NULL && !item->IsEnabled()) {
6521fc4cb1fSAxel Dörfler 		// find the next best item
6531fc4cb1fSAxel Dörfler 		int32 index = fColorsMenu->IndexOf(item);
6541fc4cb1fSAxel Dörfler 		bool found = false;
6551fc4cb1fSAxel Dörfler 
6561fc4cb1fSAxel Dörfler 		for (int32 i = index + 1; i < fColorsMenu->CountItems(); i++) {
6571fc4cb1fSAxel Dörfler 			item = fColorsMenu->ItemAt(i);
6581fc4cb1fSAxel Dörfler 			if (item->IsEnabled()) {
6591fc4cb1fSAxel Dörfler 				found = true;
6601fc4cb1fSAxel Dörfler 				break;
6611fc4cb1fSAxel Dörfler 			}
6621fc4cb1fSAxel Dörfler 		}
6631fc4cb1fSAxel Dörfler 		if (!found) {
6641fc4cb1fSAxel Dörfler 			// search backwards as well
6651fc4cb1fSAxel Dörfler 			for (int32 i = index - 1; i >= 0; i--) {
6661fc4cb1fSAxel Dörfler 				item = fColorsMenu->ItemAt(i);
6671fc4cb1fSAxel Dörfler 				if (item->IsEnabled())
6681fc4cb1fSAxel Dörfler 					break;
6691fc4cb1fSAxel Dörfler 			}
6701fc4cb1fSAxel Dörfler 		}
6711fc4cb1fSAxel Dörfler 
6721fc4cb1fSAxel Dörfler 		item->SetMarked(true);
6731fc4cb1fSAxel Dörfler 		changed = true;
6741fc4cb1fSAxel Dörfler 	}
6751fc4cb1fSAxel Dörfler 
6761fc4cb1fSAxel Dörfler 	if (changed) {
6771fc4cb1fSAxel Dörfler 		// Update selected space
6781fc4cb1fSAxel Dörfler 
6791fc4cb1fSAxel Dörfler 		BMessage* message = item->Message();
6801fc4cb1fSAxel Dörfler 		int32 space;
6811fc4cb1fSAxel Dörfler 		if (message->FindInt32("space", &space) == B_OK) {
6821fc4cb1fSAxel Dörfler 			fSelected.space = (color_space)space;
6831fc4cb1fSAxel Dörfler 			_UpdateColorLabel();
6841fc4cb1fSAxel Dörfler 		}
6851fc4cb1fSAxel Dörfler 	}
686a10cf76eSAxel Dörfler }
687a10cf76eSAxel Dörfler 
688a10cf76eSAxel Dörfler 
6895de171daSAxel Dörfler /*!	Enable/disable refresh options according to current mode. */
690a10cf76eSAxel Dörfler void
6915de171daSAxel Dörfler ScreenWindow::_CheckRefreshMenu()
692a10cf76eSAxel Dörfler {
69329e8a73aSAxel Dörfler 	float min, max;
69429e8a73aSAxel Dörfler 	if (fScreenMode.GetRefreshLimits(fSelected, min, max) != B_OK || min == max)
69529e8a73aSAxel Dörfler 		return;
696a10cf76eSAxel Dörfler 
69729e8a73aSAxel Dörfler 	for (int32 i = fRefreshMenu->CountItems(); i-- > 0;) {
69829e8a73aSAxel Dörfler 		BMenuItem* item = fRefreshMenu->ItemAt(i);
69929e8a73aSAxel Dörfler 		BMessage* message = item->Message();
70029e8a73aSAxel Dörfler 		float refresh;
70129e8a73aSAxel Dörfler 		if (message != NULL && message->FindFloat("refresh", &refresh) == B_OK)
70229e8a73aSAxel Dörfler 			item->SetEnabled(refresh >= min && refresh <= max);
703a10cf76eSAxel Dörfler 	}
704a10cf76eSAxel Dörfler }
705a10cf76eSAxel Dörfler 
706a10cf76eSAxel Dörfler 
7075de171daSAxel Dörfler /*!	Activate appropriate menu item according to selected refresh rate */
708a10cf76eSAxel Dörfler void
7095de171daSAxel Dörfler ScreenWindow::_UpdateRefreshControl()
710a10cf76eSAxel Dörfler {
7117e44de36SRene Gollent 	for (int32 i = 0; i < fRefreshMenu->CountItems(); i++) {
7127e44de36SRene Gollent 		BMenuItem* item = fRefreshMenu->ItemAt(i);
7137e44de36SRene Gollent 		if (item->Message()->FindFloat("refresh") == fSelected.refresh) {
714a10cf76eSAxel Dörfler 			item->SetMarked(true);
71526747978SAdrien Destugues 			// "Other" items only contains a refresh rate when active
71626747978SAdrien Destugues 			fOtherRefresh->SetLabel(B_TRANSLATE("Other" B_UTF8_ELLIPSIS));
717a10cf76eSAxel Dörfler 			return;
718a10cf76eSAxel Dörfler 		}
7197e44de36SRene Gollent 	}
720a10cf76eSAxel Dörfler 
721a10cf76eSAxel Dörfler 	// this is a non-standard refresh rate
7227e44de36SRene Gollent 	if (fOtherRefresh != NULL) {
723a10cf76eSAxel Dörfler 		fOtherRefresh->Message()->ReplaceFloat("refresh", fSelected.refresh);
724a10cf76eSAxel Dörfler 		fOtherRefresh->SetMarked(true);
725a10cf76eSAxel Dörfler 
7267e44de36SRene Gollent 		BString string;
7277e44de36SRene Gollent 		refresh_rate_to_string(fSelected.refresh, string);
728a10cf76eSAxel Dörfler 		fRefreshMenu->Superitem()->SetLabel(string.String());
729a10cf76eSAxel Dörfler 
730c9e8f97aSAdrien Destugues 		string.Append(B_TRANSLATE("/other" B_UTF8_ELLIPSIS));
731a10cf76eSAxel Dörfler 		fOtherRefresh->SetLabel(string.String());
732a10cf76eSAxel Dörfler 	}
7337e44de36SRene Gollent }
734a10cf76eSAxel Dörfler 
735a10cf76eSAxel Dörfler 
736a10cf76eSAxel Dörfler void
7375de171daSAxel Dörfler ScreenWindow::_UpdateMonitorView()
738a10cf76eSAxel Dörfler {
739a10cf76eSAxel Dörfler 	BMessage updateMessage(UPDATE_DESKTOP_MSG);
740a10cf76eSAxel Dörfler 	updateMessage.AddInt32("width", fSelected.width);
741a10cf76eSAxel Dörfler 	updateMessage.AddInt32("height", fSelected.height);
742a10cf76eSAxel Dörfler 
743a10cf76eSAxel Dörfler 	PostMessage(&updateMessage, fMonitorView);
744a10cf76eSAxel Dörfler }
745a10cf76eSAxel Dörfler 
746a10cf76eSAxel Dörfler 
747a10cf76eSAxel Dörfler void
7485de171daSAxel Dörfler ScreenWindow::_UpdateControls()
749a10cf76eSAxel Dörfler {
750b21d610eSAxel Dörfler 	_UpdateWorkspaceButtons();
751b21d610eSAxel Dörfler 
752a10cf76eSAxel Dörfler 	BMenuItem* item = fSwapDisplaysMenu->ItemAt((int32)fSelected.swap_displays);
753c33a865cSJohn Scipione 	if (item != NULL && !item->IsMarked())
754a10cf76eSAxel Dörfler 		item->SetMarked(true);
755a10cf76eSAxel Dörfler 
756a10cf76eSAxel Dörfler 	item = fUseLaptopPanelMenu->ItemAt((int32)fSelected.use_laptop_panel);
757c33a865cSJohn Scipione 	if (item != NULL && !item->IsMarked())
758a10cf76eSAxel Dörfler 		item->SetMarked(true);
759a10cf76eSAxel Dörfler 
760a10cf76eSAxel Dörfler 	for (int32 i = 0; i < fTVStandardMenu->CountItems(); i++) {
761a10cf76eSAxel Dörfler 		item = fTVStandardMenu->ItemAt(i);
762a10cf76eSAxel Dörfler 
763a10cf76eSAxel Dörfler 		uint32 tvStandard;
764a10cf76eSAxel Dörfler 		item->Message()->FindInt32("tv_standard", (int32 *)&tvStandard);
765a10cf76eSAxel Dörfler 		if (tvStandard == fSelected.tv_standard) {
766a10cf76eSAxel Dörfler 			if (!item->IsMarked())
767a10cf76eSAxel Dörfler 				item->SetMarked(true);
768a10cf76eSAxel Dörfler 			break;
769a10cf76eSAxel Dörfler 		}
770a10cf76eSAxel Dörfler 	}
771a10cf76eSAxel Dörfler 
7725de171daSAxel Dörfler 	_CheckResolutionMenu();
7735de171daSAxel Dörfler 	_CheckColorMenu();
7745de171daSAxel Dörfler 	_CheckRefreshMenu();
775a10cf76eSAxel Dörfler 
776a10cf76eSAxel Dörfler 	BString string;
777a10cf76eSAxel Dörfler 	resolution_to_string(fSelected, string);
778a10cf76eSAxel Dörfler 	item = fResolutionMenu->FindItem(string.String());
779a10cf76eSAxel Dörfler 
780a10cf76eSAxel Dörfler 	if (item != NULL) {
781a10cf76eSAxel Dörfler 		if (!item->IsMarked())
782a10cf76eSAxel Dörfler 			item->SetMarked(true);
783a10cf76eSAxel Dörfler 	} else {
784a10cf76eSAxel Dörfler 		// this is bad luck - if mode has been set via screen references,
785a10cf76eSAxel Dörfler 		// this case cannot occur; there are three possible solutions:
786a10cf76eSAxel Dörfler 		// 1. add a new resolution to list
787a10cf76eSAxel Dörfler 		//    - we had to remove it as soon as a "valid" one is selected
788a10cf76eSAxel Dörfler 		//    - we don't know which frequencies/bit depths are supported
789a10cf76eSAxel Dörfler 		//    - as long as we haven't the GMT formula to create
790a10cf76eSAxel Dörfler 		//      parameters for any resolution given, we cannot
791a10cf76eSAxel Dörfler 		//      really set current mode - it's just not in the list
792a10cf76eSAxel Dörfler 		// 2. choose nearest resolution
793a10cf76eSAxel Dörfler 		//    - probably a good idea, but implies coding and testing
794a10cf76eSAxel Dörfler 		// 3. choose lowest resolution
795a10cf76eSAxel Dörfler 		//    - do you really think we are so lazy? yes, we are
796a10cf76eSAxel Dörfler 		item = fResolutionMenu->ItemAt(0);
797a10cf76eSAxel Dörfler 		if (item)
798a10cf76eSAxel Dörfler 			item->SetMarked(true);
799a10cf76eSAxel Dörfler 
800a10cf76eSAxel Dörfler 		// okay - at least we set menu label to active resolution
801a10cf76eSAxel Dörfler 		fResolutionMenu->Superitem()->SetLabel(string.String());
802a10cf76eSAxel Dörfler 	}
803a10cf76eSAxel Dörfler 
804a10cf76eSAxel Dörfler 	// mark active combine mode
805a10cf76eSAxel Dörfler 	for (int32 i = 0; i < kCombineModeCount; i++) {
806a10cf76eSAxel Dörfler 		if (kCombineModes[i].mode == fSelected.combine) {
807a10cf76eSAxel Dörfler 			item = fCombineMenu->ItemAt(i);
808c33a865cSJohn Scipione 			if (item != NULL && !item->IsMarked())
809a10cf76eSAxel Dörfler 				item->SetMarked(true);
810a10cf76eSAxel Dörfler 			break;
811a10cf76eSAxel Dörfler 		}
812a10cf76eSAxel Dörfler 	}
813a10cf76eSAxel Dörfler 
814a10cf76eSAxel Dörfler 	item = fColorsMenu->ItemAt(0);
815a10cf76eSAxel Dörfler 
8161fc4cb1fSAxel Dörfler 	for (int32 i = 0, index = 0; i <  kColorSpaceCount; i++) {
8171fc4cb1fSAxel Dörfler 		if ((fSupportedColorSpaces & (1 << i)) == 0)
8181fc4cb1fSAxel Dörfler 			continue;
8191fc4cb1fSAxel Dörfler 
8201fc4cb1fSAxel Dörfler 		if (kColorSpaces[i].space == fSelected.space) {
8211fc4cb1fSAxel Dörfler 			item = fColorsMenu->ItemAt(index);
822a10cf76eSAxel Dörfler 			break;
823a10cf76eSAxel Dörfler 		}
8241fc4cb1fSAxel Dörfler 
8251fc4cb1fSAxel Dörfler 		index++;
826a10cf76eSAxel Dörfler 	}
827a10cf76eSAxel Dörfler 
828c33a865cSJohn Scipione 	if (item != NULL && !item->IsMarked())
829a10cf76eSAxel Dörfler 		item->SetMarked(true);
830a10cf76eSAxel Dörfler 
8311fc4cb1fSAxel Dörfler 	_UpdateColorLabel();
8325de171daSAxel Dörfler 	_UpdateMonitorView();
8335de171daSAxel Dörfler 	_UpdateRefreshControl();
834a10cf76eSAxel Dörfler 
8355de171daSAxel Dörfler 	_CheckApplyEnabled();
836a10cf76eSAxel Dörfler }
837a10cf76eSAxel Dörfler 
838a10cf76eSAxel Dörfler 
83912580984SAxel Dörfler /*! Reflect active mode in chosen settings */
840a10cf76eSAxel Dörfler void
8415de171daSAxel Dörfler ScreenWindow::_UpdateActiveMode()
842a10cf76eSAxel Dörfler {
843c491b5adSJohn Scipione 	_UpdateActiveMode(current_workspace());
844c491b5adSJohn Scipione }
845c491b5adSJohn Scipione 
846c491b5adSJohn Scipione 
847c491b5adSJohn Scipione void
848c491b5adSJohn Scipione ScreenWindow::_UpdateActiveMode(int32 workspace)
849c491b5adSJohn Scipione {
85012580984SAxel Dörfler 	// Usually, this function gets called after a mode
851a10cf76eSAxel Dörfler 	// has been set manually; still, as the graphics driver
852a10cf76eSAxel Dörfler 	// is free to fiddle with mode passed, we better ask
853a10cf76eSAxel Dörfler 	// what kind of mode we actually got
854c491b5adSJohn Scipione 	if (fScreenMode.Get(fActive, workspace) == B_OK) {
855a10cf76eSAxel Dörfler 		fSelected = fActive;
856a10cf76eSAxel Dörfler 
85712966d04SAxel Dörfler 		_UpdateMonitor();
858c491b5adSJohn Scipione 		_BuildSupportedColorSpaces();
8595de171daSAxel Dörfler 		_UpdateControls();
860a10cf76eSAxel Dörfler 	}
861c491b5adSJohn Scipione }
862a10cf76eSAxel Dörfler 
863a10cf76eSAxel Dörfler 
864a10cf76eSAxel Dörfler void
865b21d610eSAxel Dörfler ScreenWindow::_UpdateWorkspaceButtons()
866b21d610eSAxel Dörfler {
867b21d610eSAxel Dörfler 	uint32 columns;
868b21d610eSAxel Dörfler 	uint32 rows;
869b21d610eSAxel Dörfler 	BPrivate::get_workspaces_layout(&columns, &rows);
870b21d610eSAxel Dörfler 
871b21d610eSAxel Dörfler 	char text[32];
8725084d0d4SAlex Smith 	snprintf(text, sizeof(text), "%" B_PRId32, columns);
873b21d610eSAxel Dörfler 	fColumnsControl->SetText(text);
874b21d610eSAxel Dörfler 
8755084d0d4SAlex Smith 	snprintf(text, sizeof(text), "%" B_PRId32, rows);
876b21d610eSAxel Dörfler 	fRowsControl->SetText(text);
877b21d610eSAxel Dörfler 
878b21d610eSAxel Dörfler 	_GetColumnRowButton(true, false)->SetEnabled(columns != 1 && rows != 32);
879b21d610eSAxel Dörfler 	_GetColumnRowButton(true, true)->SetEnabled((columns + 1) * rows < 32);
880b21d610eSAxel Dörfler 	_GetColumnRowButton(false, false)->SetEnabled(rows != 1 && columns != 32);
881b21d610eSAxel Dörfler 	_GetColumnRowButton(false, true)->SetEnabled(columns * (rows + 1) < 32);
882b21d610eSAxel Dörfler }
883b21d610eSAxel Dörfler 
884b21d610eSAxel Dörfler 
885b21d610eSAxel Dörfler void
886a10cf76eSAxel Dörfler ScreenWindow::ScreenChanged(BRect frame, color_space mode)
887a10cf76eSAxel Dörfler {
888a10cf76eSAxel Dörfler 	// move window on screen, if necessary
889a10cf76eSAxel Dörfler 	if (frame.right <= Frame().right
890a10cf76eSAxel Dörfler 		&& frame.bottom <= Frame().bottom) {
891a10cf76eSAxel Dörfler 		MoveTo((frame.Width() - Frame().Width()) / 2,
892a10cf76eSAxel Dörfler 			(frame.Height() - Frame().Height()) / 2);
893a10cf76eSAxel Dörfler 	}
894a10cf76eSAxel Dörfler }
895a10cf76eSAxel Dörfler 
896a10cf76eSAxel Dörfler 
897a10cf76eSAxel Dörfler void
898a10cf76eSAxel Dörfler ScreenWindow::WorkspaceActivated(int32 workspace, bool state)
899a10cf76eSAxel Dörfler {
900c491b5adSJohn Scipione 	if (fScreenMode.GetOriginalMode(fOriginal, workspace) == B_OK) {
901c491b5adSJohn Scipione 		_UpdateActiveMode(workspace);
902a10cf76eSAxel Dörfler 
9036edaa0f6SStefano Ceccherini 		BMessage message(UPDATE_DESKTOP_COLOR_MSG);
9046edaa0f6SStefano Ceccherini 		PostMessage(&message, fMonitorView);
905a10cf76eSAxel Dörfler 	}
906c491b5adSJohn Scipione }
907a10cf76eSAxel Dörfler 
908a10cf76eSAxel Dörfler 
909a10cf76eSAxel Dörfler void
910a10cf76eSAxel Dörfler ScreenWindow::MessageReceived(BMessage* message)
911a10cf76eSAxel Dörfler {
912a10cf76eSAxel Dörfler 	switch (message->what) {
913a10cf76eSAxel Dörfler 		case WORKSPACE_CHECK_MSG:
9145de171daSAxel Dörfler 			_CheckApplyEnabled();
915a10cf76eSAxel Dörfler 			break;
916a10cf76eSAxel Dörfler 
917b21d610eSAxel Dörfler 		case kMsgWorkspaceLayoutChanged:
918a10cf76eSAxel Dörfler 		{
919b21d610eSAxel Dörfler 			int32 deltaX = 0;
920b21d610eSAxel Dörfler 			int32 deltaY = 0;
921b21d610eSAxel Dörfler 			message->FindInt32("delta_x", &deltaX);
922b21d610eSAxel Dörfler 			message->FindInt32("delta_y", &deltaY);
923b21d610eSAxel Dörfler 
924b21d610eSAxel Dörfler 			if (deltaX == 0 && deltaY == 0)
925b21d610eSAxel Dörfler 				break;
926b21d610eSAxel Dörfler 
927b21d610eSAxel Dörfler 			uint32 newColumns;
928b21d610eSAxel Dörfler 			uint32 newRows;
929b21d610eSAxel Dörfler 			BPrivate::get_workspaces_layout(&newColumns, &newRows);
930b21d610eSAxel Dörfler 
931b21d610eSAxel Dörfler 			newColumns += deltaX;
932b21d610eSAxel Dörfler 			newRows += deltaY;
933b21d610eSAxel Dörfler 			BPrivate::set_workspaces_layout(newColumns, newRows);
934b21d610eSAxel Dörfler 
935b21d610eSAxel Dörfler 			_UpdateWorkspaceButtons();
9365de171daSAxel Dörfler 			_CheckApplyEnabled();
937b21d610eSAxel Dörfler 			break;
938abc649b8SWaldemar Kornewald 		}
939b21d610eSAxel Dörfler 
940b21d610eSAxel Dörfler 		case kMsgWorkspaceColumnsChanged:
941b21d610eSAxel Dörfler 		{
942b21d610eSAxel Dörfler 			uint32 newColumns = strtoul(fColumnsControl->Text(), NULL, 10);
943b21d610eSAxel Dörfler 
944b21d610eSAxel Dörfler 			uint32 rows;
945b21d610eSAxel Dörfler 			BPrivate::get_workspaces_layout(NULL, &rows);
946b21d610eSAxel Dörfler 			BPrivate::set_workspaces_layout(newColumns, rows);
947b21d610eSAxel Dörfler 
948b21d610eSAxel Dörfler 			_UpdateWorkspaceButtons();
949b21d610eSAxel Dörfler 			_CheckApplyEnabled();
950b21d610eSAxel Dörfler 			break;
951b21d610eSAxel Dörfler 		}
952b21d610eSAxel Dörfler 
953b21d610eSAxel Dörfler 		case kMsgWorkspaceRowsChanged:
954b21d610eSAxel Dörfler 		{
955b21d610eSAxel Dörfler 			uint32 newRows = strtoul(fRowsControl->Text(), NULL, 10);
956b21d610eSAxel Dörfler 
957b21d610eSAxel Dörfler 			uint32 columns;
958b21d610eSAxel Dörfler 			BPrivate::get_workspaces_layout(&columns, NULL);
959b21d610eSAxel Dörfler 			BPrivate::set_workspaces_layout(columns, newRows);
960b21d610eSAxel Dörfler 
961b21d610eSAxel Dörfler 			_UpdateWorkspaceButtons();
962b21d610eSAxel Dörfler 			_CheckApplyEnabled();
963a10cf76eSAxel Dörfler 			break;
964a10cf76eSAxel Dörfler 		}
965a10cf76eSAxel Dörfler 
966a10cf76eSAxel Dörfler 		case POP_RESOLUTION_MSG:
967a10cf76eSAxel Dörfler 		{
968a10cf76eSAxel Dörfler 			message->FindInt32("width", &fSelected.width);
969a10cf76eSAxel Dörfler 			message->FindInt32("height", &fSelected.height);
970a10cf76eSAxel Dörfler 
9715de171daSAxel Dörfler 			_CheckColorMenu();
9725de171daSAxel Dörfler 			_CheckRefreshMenu();
973a10cf76eSAxel Dörfler 
9745de171daSAxel Dörfler 			_UpdateMonitorView();
9755de171daSAxel Dörfler 			_UpdateRefreshControl();
976a10cf76eSAxel Dörfler 
9775de171daSAxel Dörfler 			_CheckApplyEnabled();
978a10cf76eSAxel Dörfler 			break;
979a10cf76eSAxel Dörfler 		}
980a10cf76eSAxel Dörfler 
981a10cf76eSAxel Dörfler 		case POP_COLORS_MSG:
982a10cf76eSAxel Dörfler 		{
9831fc4cb1fSAxel Dörfler 			int32 space;
9841fc4cb1fSAxel Dörfler 			if (message->FindInt32("space", &space) != B_OK)
9851fc4cb1fSAxel Dörfler 				break;
986a10cf76eSAxel Dörfler 
9871fc4cb1fSAxel Dörfler 			int32 index;
9881fc4cb1fSAxel Dörfler 			if (message->FindInt32("index", &index) == B_OK
9891fc4cb1fSAxel Dörfler 				&& fColorsMenu->ItemAt(index) != NULL)
9901fc4cb1fSAxel Dörfler 				fUserSelectedColorSpace = fColorsMenu->ItemAt(index);
9911fc4cb1fSAxel Dörfler 
9921fc4cb1fSAxel Dörfler 			fSelected.space = (color_space)space;
9931fc4cb1fSAxel Dörfler 			_UpdateColorLabel();
994a10cf76eSAxel Dörfler 
9955de171daSAxel Dörfler 			_CheckApplyEnabled();
996a10cf76eSAxel Dörfler 			break;
997a10cf76eSAxel Dörfler 		}
998a10cf76eSAxel Dörfler 
999a10cf76eSAxel Dörfler 		case POP_REFRESH_MSG:
1000a40498e2SWaldemar Kornewald 		{
1001a10cf76eSAxel Dörfler 			message->FindFloat("refresh", &fSelected.refresh);
1002c9e8f97aSAdrien Destugues 			fOtherRefresh->SetLabel(B_TRANSLATE("Other" B_UTF8_ELLIPSIS));
10031fc4cb1fSAxel Dörfler 				// revert "Other…" label - it might have a refresh rate prefix
1004a10cf76eSAxel Dörfler 
10055de171daSAxel Dörfler 			_CheckApplyEnabled();
1006a10cf76eSAxel Dörfler 			break;
1007a40498e2SWaldemar Kornewald 		}
1008a10cf76eSAxel Dörfler 
1009a10cf76eSAxel Dörfler 		case POP_OTHER_REFRESH_MSG:
1010a10cf76eSAxel Dörfler 		{
101129e8a73aSAxel Dörfler 			// make sure menu shows something useful
10125de171daSAxel Dörfler 			_UpdateRefreshControl();
1013a10cf76eSAxel Dörfler 
101429e8a73aSAxel Dörfler 			float min = 0, max = 999;
101529e8a73aSAxel Dörfler 			fScreenMode.GetRefreshLimits(fSelected, min, max);
101629e8a73aSAxel Dörfler 			if (min < gMinRefresh)
101729e8a73aSAxel Dörfler 				min = gMinRefresh;
101829e8a73aSAxel Dörfler 			if (max > gMaxRefresh)
101929e8a73aSAxel Dörfler 				max = gMaxRefresh;
102029e8a73aSAxel Dörfler 
102170a2b1b5SAxel Dörfler 			monitor_info info;
102270a2b1b5SAxel Dörfler 			if (fScreenMode.GetMonitorInfo(info) == B_OK) {
102370a2b1b5SAxel Dörfler 				min = max_c(info.min_vertical_frequency, min);
102470a2b1b5SAxel Dörfler 				max = min_c(info.max_vertical_frequency, max);
102570a2b1b5SAxel Dörfler 			}
102670a2b1b5SAxel Dörfler 
1027c5d10f7aSAxel Dörfler 			RefreshWindow *fRefreshWindow = new RefreshWindow(
102870a2b1b5SAxel Dörfler 				fRefreshField->ConvertToScreen(B_ORIGIN), fSelected.refresh,
102970a2b1b5SAxel Dörfler 				min, max);
1030a10cf76eSAxel Dörfler 			fRefreshWindow->Show();
1031a10cf76eSAxel Dörfler 			break;
1032a10cf76eSAxel Dörfler 		}
1033a10cf76eSAxel Dörfler 
1034a10cf76eSAxel Dörfler 		case SET_CUSTOM_REFRESH_MSG:
1035a10cf76eSAxel Dörfler 		{
1036a10cf76eSAxel Dörfler 			// user pressed "done" in "Other…" refresh dialog;
1037a10cf76eSAxel Dörfler 			// select the refresh rate chosen
1038a10cf76eSAxel Dörfler 			message->FindFloat("refresh", &fSelected.refresh);
1039a10cf76eSAxel Dörfler 
10405de171daSAxel Dörfler 			_UpdateRefreshControl();
10415de171daSAxel Dörfler 			_CheckApplyEnabled();
1042a10cf76eSAxel Dörfler 			break;
1043a10cf76eSAxel Dörfler 		}
1044a10cf76eSAxel Dörfler 
1045a10cf76eSAxel Dörfler 		case POP_COMBINE_DISPLAYS_MSG:
1046a10cf76eSAxel Dörfler 		{
1047a10cf76eSAxel Dörfler 			// new combine mode has bee chosen
1048a10cf76eSAxel Dörfler 			int32 mode;
1049a10cf76eSAxel Dörfler 			if (message->FindInt32("mode", &mode) == B_OK)
1050a10cf76eSAxel Dörfler 				fSelected.combine = (combine_mode)mode;
1051a10cf76eSAxel Dörfler 
10525de171daSAxel Dörfler 			_CheckResolutionMenu();
10535de171daSAxel Dörfler 			_CheckApplyEnabled();
1054a10cf76eSAxel Dörfler 			break;
1055a10cf76eSAxel Dörfler 		}
1056a10cf76eSAxel Dörfler 
1057a10cf76eSAxel Dörfler 		case POP_SWAP_DISPLAYS_MSG:
1058a10cf76eSAxel Dörfler 			message->FindBool("swap", &fSelected.swap_displays);
10595de171daSAxel Dörfler 			_CheckApplyEnabled();
1060a10cf76eSAxel Dörfler 			break;
1061a10cf76eSAxel Dörfler 
1062a10cf76eSAxel Dörfler 		case POP_USE_LAPTOP_PANEL_MSG:
1063a10cf76eSAxel Dörfler 			message->FindBool("use", &fSelected.use_laptop_panel);
10645de171daSAxel Dörfler 			_CheckApplyEnabled();
1065a10cf76eSAxel Dörfler 			break;
1066a10cf76eSAxel Dörfler 
1067a10cf76eSAxel Dörfler 		case POP_TV_STANDARD_MSG:
1068a10cf76eSAxel Dörfler 			message->FindInt32("tv_standard", (int32 *)&fSelected.tv_standard);
10695de171daSAxel Dörfler 			_CheckApplyEnabled();
1070a10cf76eSAxel Dörfler 			break;
1071a10cf76eSAxel Dörfler 
1072df3f5bacSStephan Aßmus 		case BUTTON_LAUNCH_BACKGROUNDS_MSG:
10736f095d6aSRyan Leavengood 			if (be_roster->Launch(kBackgroundsSignature) == B_ALREADY_RUNNING) {
10746f095d6aSRyan Leavengood 				app_info info;
10756f095d6aSRyan Leavengood 				be_roster->GetAppInfo(kBackgroundsSignature, &info);
10766f095d6aSRyan Leavengood 				be_roster->ActivateApp(info.team);
10776f095d6aSRyan Leavengood 			}
1078df3f5bacSStephan Aßmus 			break;
1079df3f5bacSStephan Aßmus 
1080a10cf76eSAxel Dörfler 		case BUTTON_DEFAULTS_MSG:
1081a10cf76eSAxel Dörfler 		{
10824be51fe3SWaldemar Kornewald 			// TODO: get preferred settings of screen
1083a10cf76eSAxel Dörfler 			fSelected.width = 640;
1084a10cf76eSAxel Dörfler 			fSelected.height = 480;
1085a10cf76eSAxel Dörfler 			fSelected.space = B_CMAP8;
1086a10cf76eSAxel Dörfler 			fSelected.refresh = 60.0;
1087a10cf76eSAxel Dörfler 			fSelected.combine = kCombineDisable;
1088a10cf76eSAxel Dörfler 			fSelected.swap_displays = false;
1089a10cf76eSAxel Dörfler 			fSelected.use_laptop_panel = false;
1090a10cf76eSAxel Dörfler 			fSelected.tv_standard = 0;
1091a10cf76eSAxel Dörfler 
1092b21d610eSAxel Dörfler 			// TODO: workspace defaults
1093abc649b8SWaldemar Kornewald 
10945de171daSAxel Dörfler 			_UpdateControls();
1095a10cf76eSAxel Dörfler 			break;
1096a10cf76eSAxel Dörfler 		}
1097a10cf76eSAxel Dörfler 
109810e9b12fSWaldemar Kornewald 		case BUTTON_UNDO_MSG:
109961c5c89bSAxel Dörfler 			fUndoScreenMode.Revert();
11005de171daSAxel Dörfler 			_UpdateActiveMode();
1101abc649b8SWaldemar Kornewald 			break;
1102abc649b8SWaldemar Kornewald 
1103abc649b8SWaldemar Kornewald 		case BUTTON_REVERT_MSG:
1104abc649b8SWaldemar Kornewald 		{
1105abc649b8SWaldemar Kornewald 			fModified = false;
1106199893c3SAxel Dörfler 			fBootWorkspaceApplied = false;
1107abc649b8SWaldemar Kornewald 
1108b21d610eSAxel Dörfler 			// ScreenMode::Revert() assumes that we first set the correct
1109b21d610eSAxel Dörfler 			// number of workspaces
1110b21d610eSAxel Dörfler 
1111b21d610eSAxel Dörfler 			BPrivate::set_workspaces_layout(fOriginalWorkspacesColumns,
1112b21d610eSAxel Dörfler 				fOriginalWorkspacesRows);
1113b21d610eSAxel Dörfler 			_UpdateWorkspaceButtons();
1114b21d610eSAxel Dörfler 
1115a10cf76eSAxel Dörfler 			fScreenMode.Revert();
11165de171daSAxel Dörfler 			_UpdateActiveMode();
1117a10cf76eSAxel Dörfler 			break;
1118abc649b8SWaldemar Kornewald 		}
1119a10cf76eSAxel Dörfler 
1120a10cf76eSAxel Dörfler 		case BUTTON_APPLY_MSG:
11215de171daSAxel Dörfler 			_Apply();
1122a10cf76eSAxel Dörfler 			break;
1123a10cf76eSAxel Dörfler 
1124abc649b8SWaldemar Kornewald 		case MAKE_INITIAL_MSG:
1125abc649b8SWaldemar Kornewald 			// user pressed "keep" in confirmation dialog
1126abc649b8SWaldemar Kornewald 			fModified = true;
11275de171daSAxel Dörfler 			_UpdateActiveMode();
1128a10cf76eSAxel Dörfler 			break;
1129a10cf76eSAxel Dörfler 
1130a10cf76eSAxel Dörfler 		default:
1131a10cf76eSAxel Dörfler 			BWindow::MessageReceived(message);
1132a10cf76eSAxel Dörfler 			break;
1133a10cf76eSAxel Dörfler 	}
1134a10cf76eSAxel Dörfler }
1135a10cf76eSAxel Dörfler 
1136a10cf76eSAxel Dörfler 
113712580984SAxel Dörfler status_t
113812580984SAxel Dörfler ScreenWindow::_WriteVesaModeFile(const screen_mode& mode) const
113912580984SAxel Dörfler {
114012580984SAxel Dörfler 	BPath path;
114112580984SAxel Dörfler 	status_t status = find_directory(B_USER_SETTINGS_DIRECTORY, &path, true);
114212580984SAxel Dörfler 	if (status < B_OK)
114312580984SAxel Dörfler 		return status;
114412580984SAxel Dörfler 
114512580984SAxel Dörfler 	path.Append("kernel/drivers");
114612580984SAxel Dörfler 	status = create_directory(path.Path(), 0755);
114712580984SAxel Dörfler 	if (status < B_OK)
114812580984SAxel Dörfler 		return status;
114912580984SAxel Dörfler 
115012580984SAxel Dörfler 	path.Append("vesa");
115112580984SAxel Dörfler 	BFile file;
115212580984SAxel Dörfler 	status = file.SetTo(path.Path(), B_CREATE_FILE | B_WRITE_ONLY | B_ERASE_FILE);
115312580984SAxel Dörfler 	if (status < B_OK)
115412580984SAxel Dörfler 		return status;
115512580984SAxel Dörfler 
115612580984SAxel Dörfler 	char buffer[256];
11575084d0d4SAlex Smith 	snprintf(buffer, sizeof(buffer), "mode %" B_PRId32 " %" B_PRId32 " %"
11585084d0d4SAlex Smith 		B_PRId32 "\n", mode.width, mode.height, mode.BitsPerPixel());
115912580984SAxel Dörfler 
116012580984SAxel Dörfler 	ssize_t bytesWritten = file.Write(buffer, strlen(buffer));
116112580984SAxel Dörfler 	if (bytesWritten < B_OK)
116212580984SAxel Dörfler 		return bytesWritten;
116312580984SAxel Dörfler 
116412580984SAxel Dörfler 	return B_OK;
116512580984SAxel Dörfler }
116612580984SAxel Dörfler 
116712580984SAxel Dörfler 
1168b21d610eSAxel Dörfler BButton*
1169b21d610eSAxel Dörfler ScreenWindow::_CreateColumnRowButton(bool columns, bool plus)
1170b21d610eSAxel Dörfler {
1171b21d610eSAxel Dörfler 	BMessage* message = new BMessage(kMsgWorkspaceLayoutChanged);
1172b21d610eSAxel Dörfler 	message->AddInt32("delta_x", columns ? (plus ? 1 : -1) : 0);
1173b21d610eSAxel Dörfler 	message->AddInt32("delta_y", !columns ? (plus ? 1 : -1) : 0);
1174b21d610eSAxel Dörfler 
1175b21d610eSAxel Dörfler 	BButton* button = new BButton(plus ? "+" : "-", message);
1176b21d610eSAxel Dörfler 	button->SetFontSize(be_plain_font->Size() * 0.9);
1177b21d610eSAxel Dörfler 
1178b21d610eSAxel Dörfler 	BSize size = button->MinSize();
1179b21d610eSAxel Dörfler 	size.width = button->StringWidth("+") + 16;
1180b21d610eSAxel Dörfler 	button->SetExplicitMinSize(size);
1181b21d610eSAxel Dörfler 	button->SetExplicitMaxSize(size);
1182b21d610eSAxel Dörfler 
1183b21d610eSAxel Dörfler 	fWorkspacesButtons[(columns ? 0 : 2) + (plus ? 1 : 0)] = button;
1184b21d610eSAxel Dörfler 	return button;
1185b21d610eSAxel Dörfler }
1186b21d610eSAxel Dörfler 
1187b21d610eSAxel Dörfler 
1188b21d610eSAxel Dörfler BButton*
1189b21d610eSAxel Dörfler ScreenWindow::_GetColumnRowButton(bool columns, bool plus)
1190b21d610eSAxel Dörfler {
1191b21d610eSAxel Dörfler 	return fWorkspacesButtons[(columns ? 0 : 2) + (plus ? 1 : 0)];
1192b21d610eSAxel Dörfler }
1193b21d610eSAxel Dörfler 
1194b21d610eSAxel Dörfler 
1195a10cf76eSAxel Dörfler void
11961fc4cb1fSAxel Dörfler ScreenWindow::_BuildSupportedColorSpaces()
11971fc4cb1fSAxel Dörfler {
11981fc4cb1fSAxel Dörfler 	fSupportedColorSpaces = 0;
11991fc4cb1fSAxel Dörfler 
12001fc4cb1fSAxel Dörfler 	for (int32 i = 0; i < kColorSpaceCount; i++) {
12011fc4cb1fSAxel Dörfler 		for (int32 j = 0; j < fScreenMode.CountModes(); j++) {
12021fc4cb1fSAxel Dörfler 			if (fScreenMode.ModeAt(j).space == kColorSpaces[i].space) {
12031fc4cb1fSAxel Dörfler 				fSupportedColorSpaces |= 1 << i;
12041fc4cb1fSAxel Dörfler 				break;
12051fc4cb1fSAxel Dörfler 			}
12061fc4cb1fSAxel Dörfler 		}
12071fc4cb1fSAxel Dörfler 	}
12081fc4cb1fSAxel Dörfler }
12091fc4cb1fSAxel Dörfler 
12101fc4cb1fSAxel Dörfler 
12111fc4cb1fSAxel Dörfler void
12125de171daSAxel Dörfler ScreenWindow::_CheckApplyEnabled()
1213a10cf76eSAxel Dörfler {
121427c43a2dSRene Gollent 	fApplyButton->SetEnabled(fSelected != fActive
121527c43a2dSRene Gollent 		|| fAllWorkspacesItem->IsMarked());
1216b21d610eSAxel Dörfler 
1217b21d610eSAxel Dörfler 	uint32 columns;
1218b21d610eSAxel Dörfler 	uint32 rows;
1219b21d610eSAxel Dörfler 	BPrivate::get_workspaces_layout(&columns, &rows);
1220b21d610eSAxel Dörfler 
1221b21d610eSAxel Dörfler 	fRevertButton->SetEnabled(columns != fOriginalWorkspacesColumns
1222b21d610eSAxel Dörfler 		|| rows != fOriginalWorkspacesRows
12235de171daSAxel Dörfler 		|| fSelected != fOriginal);
1224a10cf76eSAxel Dörfler }
1225a10cf76eSAxel Dörfler 
1226a10cf76eSAxel Dörfler 
1227a10cf76eSAxel Dörfler void
12285de171daSAxel Dörfler ScreenWindow::_UpdateOriginal()
1229abc649b8SWaldemar Kornewald {
1230b21d610eSAxel Dörfler 	BPrivate::get_workspaces_layout(&fOriginalWorkspacesColumns,
1231b21d610eSAxel Dörfler 		&fOriginalWorkspacesRows);
1232b21d610eSAxel Dörfler 
1233abc649b8SWaldemar Kornewald 	fScreenMode.Get(fOriginal);
1234abc649b8SWaldemar Kornewald 	fScreenMode.UpdateOriginalModes();
1235abc649b8SWaldemar Kornewald }
1236abc649b8SWaldemar Kornewald 
1237abc649b8SWaldemar Kornewald 
1238abc649b8SWaldemar Kornewald void
123912966d04SAxel Dörfler ScreenWindow::_UpdateMonitor()
124012966d04SAxel Dörfler {
124112966d04SAxel Dörfler 	monitor_info info;
124212966d04SAxel Dörfler 	float diagonalInches;
124312966d04SAxel Dörfler 	status_t status = fScreenMode.GetMonitorInfo(info, &diagonalInches);
124455030977SAxel Dörfler 	if (status == B_OK) {
12451a8af605SAxel Dörfler 		char text[512];
124666ab1666SAxel Dörfler 		snprintf(text, sizeof(text), "%s%s%s %g\"", info.vendor,
124766ab1666SAxel Dörfler 			info.name[0] ? " " : "", info.name, diagonalInches);
124812966d04SAxel Dörfler 
124912966d04SAxel Dörfler 		fMonitorInfo->SetText(text);
125012966d04SAxel Dörfler 
125112966d04SAxel Dörfler 		if (fMonitorInfo->IsHidden())
125212966d04SAxel Dörfler 			fMonitorInfo->Show();
125355030977SAxel Dörfler 	} else {
125455030977SAxel Dörfler 		if (!fMonitorInfo->IsHidden())
125555030977SAxel Dörfler 			fMonitorInfo->Hide();
125655030977SAxel Dörfler 	}
1257af8f9c31SAxel Dörfler 
125855030977SAxel Dörfler 	char text[512];
12591a8af605SAxel Dörfler 	size_t length = 0;
12601a8af605SAxel Dörfler 	text[0] = 0;
12611a8af605SAxel Dörfler 
126255030977SAxel Dörfler 	if (status == B_OK) {
1263af8f9c31SAxel Dörfler 		if (info.min_horizontal_frequency != 0
1264af8f9c31SAxel Dörfler 			&& info.min_vertical_frequency != 0
1265af8f9c31SAxel Dörfler 			&& info.max_pixel_clock != 0) {
12661a8af605SAxel Dörfler 			length = snprintf(text, sizeof(text),
1267c9e8f97aSAdrien Destugues 				B_TRANSLATE("Horizonal frequency:\t%lu - %lu kHz\n"
12689c1a9b92SAdrien Destugues 				"Vertical frequency:\t%lu - %lu Hz\n\n"
1269c9e8f97aSAdrien Destugues 				"Maximum pixel clock:\t%g MHz"),
12701a8af605SAxel Dörfler 				info.min_horizontal_frequency, info.max_horizontal_frequency,
12711a8af605SAxel Dörfler 				info.min_vertical_frequency, info.max_vertical_frequency,
12721a8af605SAxel Dörfler 				info.max_pixel_clock / 1000.0);
1273af8f9c31SAxel Dörfler 		}
12741a8af605SAxel Dörfler 		if (info.serial_number[0] && length < sizeof(text)) {
12751a8af605SAxel Dörfler 			length += snprintf(text + length, sizeof(text) - length,
1276c9e8f97aSAdrien Destugues 				B_TRANSLATE("%sSerial no.: %s"), length ? "\n\n" : "",
12771a8af605SAxel Dörfler 				info.serial_number);
12781a8af605SAxel Dörfler 			if (info.produced.week != 0 && info.produced.year != 0
12791a8af605SAxel Dörfler 				&& length < sizeof(text)) {
12801a8af605SAxel Dörfler 				length += snprintf(text + length, sizeof(text) - length,
12811a8af605SAxel Dörfler 					" (%u/%u)", info.produced.week, info.produced.year);
12821a8af605SAxel Dörfler 	 		}
12831a8af605SAxel Dörfler 		}
128455030977SAxel Dörfler 	}
128561c5c89bSAxel Dörfler 
128661c5c89bSAxel Dörfler 	// Add info about the graphics device
128761c5c89bSAxel Dörfler 
128861c5c89bSAxel Dörfler 	accelerant_device_info deviceInfo;
128961c5c89bSAxel Dörfler 	if (fScreenMode.GetDeviceInfo(deviceInfo) == B_OK
129061c5c89bSAxel Dörfler 		&& length < sizeof(text)) {
129161c5c89bSAxel Dörfler 		if (deviceInfo.name[0] && deviceInfo.chipset[0]) {
129261c5c89bSAxel Dörfler 			length += snprintf(text + length, sizeof(text) - length,
129361c5c89bSAxel Dörfler 				"%s%s (%s)", length != 0 ? "\n\n" : "", deviceInfo.name,
129461c5c89bSAxel Dörfler 				deviceInfo.chipset);
129561c5c89bSAxel Dörfler 		} else if (deviceInfo.name[0] || deviceInfo.chipset[0]) {
129661c5c89bSAxel Dörfler 			length += snprintf(text + length, sizeof(text) - length,
129761c5c89bSAxel Dörfler 				"%s%s", length != 0 ? "\n\n" : "", deviceInfo.name[0]
129861c5c89bSAxel Dörfler 					? deviceInfo.name : deviceInfo.chipset);
129961c5c89bSAxel Dörfler 		}
130061c5c89bSAxel Dörfler 	}
130161c5c89bSAxel Dörfler 
13021a8af605SAxel Dörfler 	if (text[0])
13031a8af605SAxel Dörfler 		fMonitorView->SetToolTip(text);
130412966d04SAxel Dörfler }
130512966d04SAxel Dörfler 
130612966d04SAxel Dörfler 
130712966d04SAxel Dörfler void
13081fc4cb1fSAxel Dörfler ScreenWindow::_UpdateColorLabel()
13091fc4cb1fSAxel Dörfler {
13101fc4cb1fSAxel Dörfler 	BString string;
1311551c9f15SSiarzhuk Zharski 	string << fSelected.BitsPerPixel() << " " << B_TRANSLATE("bits/pixel");
13121fc4cb1fSAxel Dörfler 	fColorsMenu->Superitem()->SetLabel(string.String());
13131fc4cb1fSAxel Dörfler }
13141fc4cb1fSAxel Dörfler 
13151fc4cb1fSAxel Dörfler 
13161fc4cb1fSAxel Dörfler void
13175de171daSAxel Dörfler ScreenWindow::_Apply()
1318a10cf76eSAxel Dörfler {
1319abc649b8SWaldemar Kornewald 	// make checkpoint, so we can undo these changes
132061c5c89bSAxel Dörfler 	fUndoScreenMode.UpdateOriginalModes();
132161c5c89bSAxel Dörfler 
132207184a9eSAxel Dörfler 	status_t status = fScreenMode.Set(fSelected);
132307184a9eSAxel Dörfler 	if (status == B_OK) {
1324abc649b8SWaldemar Kornewald 		// use the mode that has eventually been set and
1325abc649b8SWaldemar Kornewald 		// thus we know to be working; it can differ from
1326abc649b8SWaldemar Kornewald 		// the mode selected by user due to hardware limitation
1327abc649b8SWaldemar Kornewald 		display_mode newMode;
1328abc649b8SWaldemar Kornewald 		BScreen screen(this);
1329abc649b8SWaldemar Kornewald 		screen.GetMode(&newMode);
1330abc649b8SWaldemar Kornewald 
1331abc649b8SWaldemar Kornewald 		if (fAllWorkspacesItem->IsMarked()) {
1332abc649b8SWaldemar Kornewald 			int32 originatingWorkspace = current_workspace();
1333abc649b8SWaldemar Kornewald 			for (int32 i = 0; i < count_workspaces(); i++) {
1334abc649b8SWaldemar Kornewald 				if (i != originatingWorkspace)
1335abc649b8SWaldemar Kornewald 					screen.SetMode(i, &newMode, true);
1336abc649b8SWaldemar Kornewald 			}
1337199893c3SAxel Dörfler 			fBootWorkspaceApplied = true;
1338199893c3SAxel Dörfler 		} else {
1339199893c3SAxel Dörfler 			if (current_workspace() == 0)
1340199893c3SAxel Dörfler 				fBootWorkspaceApplied = true;
1341abc649b8SWaldemar Kornewald 		}
1342abc649b8SWaldemar Kornewald 
1343a10cf76eSAxel Dörfler 		fActive = fSelected;
1344a10cf76eSAxel Dörfler 
1345abc649b8SWaldemar Kornewald 		// TODO: only show alert when this is an unknown mode
1346a10cf76eSAxel Dörfler 		BWindow* window = new AlertWindow(this);
1347a10cf76eSAxel Dörfler 		window->Show();
134807184a9eSAxel Dörfler 	} else {
134907184a9eSAxel Dörfler 		char message[256];
135007184a9eSAxel Dörfler 		snprintf(message, sizeof(message),
1351c9e8f97aSAdrien Destugues 			B_TRANSLATE("The screen mode could not be set:\n\t%s\n"),
1352c9e8f97aSAdrien Destugues 			screen_errors(status));
1353551c9f15SSiarzhuk Zharski 		BAlert* alert = new BAlert(B_TRANSLATE("Warning"), message,
1354c9e8f97aSAdrien Destugues 			B_TRANSLATE("OK"), NULL, NULL,
135507184a9eSAxel Dörfler 			B_WIDTH_AS_USUAL, B_WARNING_ALERT);
1356aed35104SHumdinger 		alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE);
135707184a9eSAxel Dörfler 		alert->Go();
1358a10cf76eSAxel Dörfler 	}
135907184a9eSAxel Dörfler }
1360