xref: /haiku/src/preferences/screen/ScreenWindow.cpp (revision 4dcc9761a72d1241d20a1a1154cc40cacd94f534)
1a10cf76eSAxel Dörfler /*
28bf216d6SAxel Dörfler  * Copyright 2001-2015 Haiku, Inc. All rights reserved.
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>
43a3fa81bdSJohn Scipione #include <Spinner.h>
44b21d610eSAxel Dörfler #include <String.h>
45b21d610eSAxel Dörfler #include <StringView.h>
46b21d610eSAxel Dörfler #include <Roster.h>
47b21d610eSAxel Dörfler #include <Window.h>
48b21d610eSAxel Dörfler 
49b21d610eSAxel Dörfler #include <InterfacePrivate.h>
50b21d610eSAxel Dörfler 
51a10cf76eSAxel Dörfler #include "AlertWindow.h"
52a10cf76eSAxel Dörfler #include "Constants.h"
53a10cf76eSAxel Dörfler #include "RefreshWindow.h"
54a10cf76eSAxel Dörfler #include "MonitorView.h"
55a10cf76eSAxel Dörfler #include "ScreenSettings.h"
56a10cf76eSAxel Dörfler #include "Utility.h"
57a10cf76eSAxel Dörfler 
58a10cf76eSAxel Dörfler /* Note, this headers defines a *private* interface to the Radeon accelerant.
59a10cf76eSAxel Dörfler  * It's a solution that works with the current BeOS interface that Haiku
60a10cf76eSAxel Dörfler  * adopted.
61a10cf76eSAxel Dörfler  * However, it's not a nice and clean solution. Don't use this header in any
62a10cf76eSAxel Dörfler  * application if you can avoid it. No other driver is using this, or should
63a10cf76eSAxel Dörfler  * be using this.
64a10cf76eSAxel Dörfler  * It will be replaced as soon as we introduce an updated accelerant interface
65a10cf76eSAxel Dörfler  * which may even happen before R1 hits the streets.
66a10cf76eSAxel Dörfler  */
67a10cf76eSAxel Dörfler #include "multimon.h"	// the usual: DANGER WILL, ROBINSON!
68a10cf76eSAxel Dörfler 
69a10cf76eSAxel Dörfler 
70546208a5SOliver Tappe #undef B_TRANSLATION_CONTEXT
71546208a5SOliver Tappe #define B_TRANSLATION_CONTEXT "Screen"
72c9e8f97aSAdrien Destugues 
73c9e8f97aSAdrien Destugues 
7475c92c56SRyan Leavengood const char* kBackgroundsSignature = "application/x-vnd.Haiku-Backgrounds";
75c5d80d47SAxel Dörfler 
76a10cf76eSAxel Dörfler // list of officially supported colour spaces
77a10cf76eSAxel Dörfler static const struct {
78a10cf76eSAxel Dörfler 	color_space	space;
79a10cf76eSAxel Dörfler 	int32		bits_per_pixel;
80a10cf76eSAxel Dörfler 	const char*	label;
81a10cf76eSAxel Dörfler } kColorSpaces[] = {
8226747978SAdrien Destugues 	{ B_CMAP8, 8, B_TRANSLATE("8 bits/pixel, 256 colors") },
83c9e8f97aSAdrien Destugues 	{ B_RGB15, 15, B_TRANSLATE("15 bits/pixel, 32768 colors") },
84c9e8f97aSAdrien Destugues 	{ B_RGB16, 16, B_TRANSLATE("16 bits/pixel, 65536 colors") },
85c9e8f97aSAdrien Destugues 	{ B_RGB24, 24, B_TRANSLATE("24 bits/pixel, 16 Million colors") },
86c9e8f97aSAdrien Destugues 	{ B_RGB32, 32, B_TRANSLATE("32 bits/pixel, 16 Million colors") }
87a10cf76eSAxel Dörfler };
88b21d610eSAxel Dörfler static const int32 kColorSpaceCount
89b21d610eSAxel Dörfler 	= sizeof(kColorSpaces) / sizeof(kColorSpaces[0]);
90a10cf76eSAxel Dörfler 
91a10cf76eSAxel Dörfler // list of standard refresh rates
92a796facfSAxel Dörfler static const int32 kRefreshRates[] = { 60, 70, 72, 75, 80, 85, 95, 100 };
93b21d610eSAxel Dörfler static const int32 kRefreshRateCount
94b21d610eSAxel Dörfler 	= sizeof(kRefreshRates) / sizeof(kRefreshRates[0]);
95a10cf76eSAxel Dörfler 
96a10cf76eSAxel Dörfler // list of combine modes
97a10cf76eSAxel Dörfler static const struct {
98a10cf76eSAxel Dörfler 	combine_mode	mode;
99a10cf76eSAxel Dörfler 	const char		*name;
100a10cf76eSAxel Dörfler } kCombineModes[] = {
101c9e8f97aSAdrien Destugues 	{ kCombineDisable, B_TRANSLATE("disable") },
102c9e8f97aSAdrien Destugues 	{ kCombineHorizontally, B_TRANSLATE("horizontally") },
103c9e8f97aSAdrien Destugues 	{ kCombineVertically, B_TRANSLATE("vertically") }
104a10cf76eSAxel Dörfler };
105b21d610eSAxel Dörfler static const int32 kCombineModeCount
106b21d610eSAxel Dörfler 	= sizeof(kCombineModes) / sizeof(kCombineModes[0]);
10729e8a73aSAxel Dörfler 
108a10cf76eSAxel Dörfler 
109a10cf76eSAxel Dörfler static BString
110a10cf76eSAxel Dörfler tv_standard_to_string(uint32 mode)
111a10cf76eSAxel Dörfler {
112a10cf76eSAxel Dörfler 	switch (mode) {
113a10cf76eSAxel Dörfler 		case 0:		return "disabled";
114a10cf76eSAxel Dörfler 		case 1:		return "NTSC";
115a10cf76eSAxel Dörfler 		case 2:		return "NTSC Japan";
116a10cf76eSAxel Dörfler 		case 3:		return "PAL BDGHI";
117a10cf76eSAxel Dörfler 		case 4:		return "PAL M";
118a10cf76eSAxel Dörfler 		case 5:		return "PAL N";
119a10cf76eSAxel Dörfler 		case 6:		return "SECAM";
120a10cf76eSAxel Dörfler 		case 101:	return "NTSC 443";
121a10cf76eSAxel Dörfler 		case 102:	return "PAL 60";
122a10cf76eSAxel Dörfler 		case 103:	return "PAL NC";
123a10cf76eSAxel Dörfler 		default:
124a10cf76eSAxel Dörfler 		{
125a10cf76eSAxel Dörfler 			BString name;
126a10cf76eSAxel Dörfler 			name << "??? (" << mode << ")";
127a10cf76eSAxel Dörfler 
128a10cf76eSAxel Dörfler 			return name;
129a10cf76eSAxel Dörfler 		}
130a10cf76eSAxel Dörfler 	}
131a10cf76eSAxel Dörfler }
132a10cf76eSAxel Dörfler 
133a10cf76eSAxel Dörfler 
134a10cf76eSAxel Dörfler static void
135a10cf76eSAxel Dörfler resolution_to_string(screen_mode& mode, BString &string)
136a10cf76eSAxel Dörfler {
137a10cf76eSAxel Dörfler 	string << mode.width << " x " << mode.height;
138a10cf76eSAxel Dörfler }
139a10cf76eSAxel Dörfler 
140a10cf76eSAxel Dörfler 
141a10cf76eSAxel Dörfler static void
142a10cf76eSAxel Dörfler refresh_rate_to_string(float refresh, BString &string,
143a10cf76eSAxel Dörfler 	bool appendUnit = true, bool alwaysWithFraction = false)
144a10cf76eSAxel Dörfler {
1458bf23e3cSAxel Dörfler 	snprintf(string.LockBuffer(32), 32, "%.*g", refresh >= 100.0 ? 4 : 3,
1468bf23e3cSAxel Dörfler 		refresh);
147a10cf76eSAxel Dörfler 	string.UnlockBuffer();
148a10cf76eSAxel Dörfler 
149a10cf76eSAxel Dörfler 	if (appendUnit)
150551c9f15SSiarzhuk Zharski 		string << " " << B_TRANSLATE("Hz");
151a10cf76eSAxel Dörfler }
152a10cf76eSAxel Dörfler 
153a10cf76eSAxel Dörfler 
15407184a9eSAxel Dörfler static const char*
15507184a9eSAxel Dörfler screen_errors(status_t status)
15607184a9eSAxel Dörfler {
15707184a9eSAxel Dörfler 	switch (status) {
15807184a9eSAxel Dörfler 		case B_ENTRY_NOT_FOUND:
159c9e8f97aSAdrien Destugues 			return B_TRANSLATE("Unknown mode");
16007184a9eSAxel Dörfler 		// TODO: add more?
16107184a9eSAxel Dörfler 
16207184a9eSAxel Dörfler 		default:
16307184a9eSAxel Dörfler 			return strerror(status);
16407184a9eSAxel Dörfler 	}
16507184a9eSAxel Dörfler }
16607184a9eSAxel Dörfler 
16729e8a73aSAxel Dörfler 
168a3fa81bdSJohn Scipione //	#pragma mark - ScreenWindow
1693dfd20c0SStephan Aßmus 
1703dfd20c0SStephan Aßmus 
1715a78744bSAxel Dörfler ScreenWindow::ScreenWindow(ScreenSettings* settings)
172b21d610eSAxel Dörfler 	:
173560ff447SJonas Sundström 	BWindow(settings->WindowFrame(), B_TRANSLATE_SYSTEM_NAME("Screen"),
174958e0ca5SJohn Scipione 		B_TITLED_WINDOW, B_NOT_RESIZABLE | B_NOT_ZOOMABLE
175958e0ca5SJohn Scipione 			| B_AUTO_UPDATE_SIZE_LIMITS, B_ALL_WORKSPACES),
1763f953a72SAxel Dörfler 	fIsVesa(false),
177199893c3SAxel Dörfler 	fBootWorkspaceApplied(false),
1787e44de36SRene Gollent 	fOtherRefresh(NULL),
179294a85aaSRene Gollent 	fScreenMode(this),
18061c5c89bSAxel Dörfler 	fUndoScreenMode(this),
181abc649b8SWaldemar Kornewald 	fModified(false)
182a10cf76eSAxel Dörfler {
183a10cf76eSAxel Dörfler 	BScreen screen(this);
184a10cf76eSAxel Dörfler 
18512580984SAxel Dörfler 	accelerant_device_info info;
186d1516993SAxel Dörfler 	if (screen.GetDeviceInfo(&info) == B_OK
187d1516993SAxel Dörfler 		&& !strcasecmp(info.chipset, "VESA"))
18812580984SAxel Dörfler 		fIsVesa = true;
18912580984SAxel Dörfler 
1905de171daSAxel Dörfler 	_UpdateOriginal();
1911fc4cb1fSAxel Dörfler 	_BuildSupportedColorSpaces();
192a10cf76eSAxel Dörfler 	fActive = fSelected = fOriginal;
193a10cf76eSAxel Dörfler 
1945a78744bSAxel Dörfler 	fSettings = settings;
1955a78744bSAxel Dörfler 
1965a78744bSAxel Dörfler 	// we need the "Current Workspace" first to get its height
1975a78744bSAxel Dörfler 
198c9e8f97aSAdrien Destugues 	BPopUpMenu* popUpMenu = new BPopUpMenu(B_TRANSLATE("Current workspace"),
199c9e8f97aSAdrien Destugues 		true, true);
200c9e8f97aSAdrien Destugues 	fAllWorkspacesItem = new BMenuItem(B_TRANSLATE("All workspaces"),
201d1516993SAxel Dörfler 		new BMessage(WORKSPACE_CHECK_MSG));
2025a78744bSAxel Dörfler 	popUpMenu->AddItem(fAllWorkspacesItem);
203c9e8f97aSAdrien Destugues 	BMenuItem *item = new BMenuItem(B_TRANSLATE("Current workspace"),
204d1516993SAxel Dörfler 		new BMessage(WORKSPACE_CHECK_MSG));
205b72c4836SAlexandre Deckner 
2065a78744bSAxel Dörfler 	popUpMenu->AddItem(item);
20727c43a2dSRene Gollent 	fAllWorkspacesItem->SetMarked(true);
2085a78744bSAxel Dörfler 
209b21d610eSAxel Dörfler 	BMenuField* workspaceMenuField = new BMenuField("WorkspaceMenu", NULL,
21010dfe897SAxel Dörfler 		popUpMenu);
2115a78744bSAxel Dörfler 	workspaceMenuField->ResizeToPreferred();
212a10cf76eSAxel Dörfler 
213a10cf76eSAxel Dörfler 	// box on the left with workspace count and monitor view
214a10cf76eSAxel Dörfler 
215b21d610eSAxel Dörfler 	BBox* screenBox = new BBox("screen box");
216e1c88201SJohn Scipione 	BGroupLayout* layout = new BGroupLayout(B_VERTICAL, B_USE_SMALL_SPACING);
217e1c88201SJohn Scipione 	layout->SetInsets(B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING,
218e1c88201SJohn Scipione 		B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING);
219b21d610eSAxel Dörfler 	screenBox->SetLayout(layout);
220a10cf76eSAxel Dörfler 
22112966d04SAxel Dörfler 	fMonitorInfo = new BStringView("monitor info", "");
222e1c88201SJohn Scipione 	fMonitorInfo->SetAlignment(B_ALIGN_CENTER);
22312966d04SAxel Dörfler 	screenBox->AddChild(fMonitorInfo);
22412966d04SAxel Dörfler 
2258b46ee25SAdrien Destugues 	fDeviceInfo = new BStringView("monitor info", "");
2268b46ee25SAdrien Destugues 	fDeviceInfo->SetAlignment(B_ALIGN_CENTER);
2278b46ee25SAdrien Destugues 	screenBox->AddChild(fDeviceInfo);
2288b46ee25SAdrien Destugues 
2298bf216d6SAxel Dörfler 	float scaling = std::max(1.0f, be_plain_font->Size() / 12.0f);
2308bf216d6SAxel Dörfler 	fMonitorView = new MonitorView(BRect(0.0, 0.0, 80.0 * scaling,
2318bf216d6SAxel Dörfler 			80.0 * scaling), "monitor", screen.Frame().IntegerWidth() + 1,
232c9e8f97aSAdrien Destugues 		screen.Frame().IntegerHeight() + 1);
233b21d610eSAxel Dörfler 	screenBox->AddChild(fMonitorView);
2345a78744bSAxel Dörfler 
235e1c88201SJohn Scipione 	BStringView* workspaces = new BStringView("workspaces",
236e1c88201SJohn Scipione 		B_TRANSLATE("Workspaces"));
237e1c88201SJohn Scipione 	workspaces->SetAlignment(B_ALIGN_CENTER);
238e1c88201SJohn Scipione 
239a3fa81bdSJohn Scipione 	fColumnsControl = new BSpinner("columns", B_TRANSLATE("Columns:"),
240b21d610eSAxel Dörfler 		new BMessage(kMsgWorkspaceColumnsChanged));
241a3fa81bdSJohn Scipione 	fColumnsControl->SetAlignment(B_ALIGN_RIGHT);
242a3fa81bdSJohn Scipione 	fColumnsControl->SetRange(1, 32);
243b21d610eSAxel Dörfler 
244a3fa81bdSJohn Scipione 	fRowsControl = new BSpinner("rows", B_TRANSLATE("Rows:"),
245a3fa81bdSJohn Scipione 		new BMessage(kMsgWorkspaceRowsChanged));
246a3fa81bdSJohn Scipione 	fRowsControl->SetAlignment(B_ALIGN_RIGHT);
247a3fa81bdSJohn Scipione 	fRowsControl->SetRange(1, 32);
248a3fa81bdSJohn Scipione 
249a3fa81bdSJohn Scipione 	uint32 columns;
250a3fa81bdSJohn Scipione 	uint32 rows;
251a3fa81bdSJohn Scipione 	BPrivate::get_workspaces_layout(&columns, &rows);
252a3fa81bdSJohn Scipione 	fColumnsControl->SetValue(columns);
253a3fa81bdSJohn Scipione 	fRowsControl->SetValue(rows);
254a3fa81bdSJohn Scipione 
255e1c88201SJohn Scipione 	screenBox->AddChild(BLayoutBuilder::Group<>()
256e1c88201SJohn Scipione 		.AddGroup(B_VERTICAL, B_USE_SMALL_SPACING)
257e1c88201SJohn Scipione 			.Add(workspaces)
258*4dcc9761SJohn Scipione 			.AddGroup(B_HORIZONTAL, 0)
259*4dcc9761SJohn Scipione 				.AddGlue()
260a3fa81bdSJohn Scipione 				.AddGrid(B_USE_DEFAULT_SPACING, B_USE_SMALL_SPACING)
261e1c88201SJohn Scipione 					// columns
262e1c88201SJohn Scipione 					.Add(fColumnsControl->CreateLabelLayoutItem(), 0, 0)
263a3fa81bdSJohn Scipione 					.Add(fColumnsControl->CreateTextViewLayoutItem(), 1, 0)
264e1c88201SJohn Scipione 					// rows
265e1c88201SJohn Scipione 					.Add(fRowsControl->CreateLabelLayoutItem(), 0, 1)
266a3fa81bdSJohn Scipione 					.Add(fRowsControl->CreateTextViewLayoutItem(), 1, 1)
267b21d610eSAxel Dörfler 					.End()
268*4dcc9761SJohn Scipione 				.AddGlue()
269*4dcc9761SJohn Scipione 				.End()
27025fd5c7bSAlex Wilson 			.End()
27125fd5c7bSAlex Wilson 		.View());
272b21d610eSAxel Dörfler 
273b21d610eSAxel Dörfler 	fBackgroundsButton = new BButton("BackgroundsButton",
274c9e8f97aSAdrien Destugues 		B_TRANSLATE("Set background" B_UTF8_ELLIPSIS),
275b21d610eSAxel Dörfler 		new BMessage(BUTTON_LAUNCH_BACKGROUNDS_MSG));
276b21d610eSAxel Dörfler 	fBackgroundsButton->SetFontSize(be_plain_font->Size() * 0.9);
277b21d610eSAxel Dörfler 	screenBox->AddChild(fBackgroundsButton);
278a10cf76eSAxel Dörfler 
279a10cf76eSAxel Dörfler 	// box on the right with screen resolution, etc.
280a10cf76eSAxel Dörfler 
281b21d610eSAxel Dörfler 	BBox* controlsBox = new BBox("controls box");
282b21d610eSAxel Dörfler 	controlsBox->SetLabel(workspaceMenuField);
2836048f541SJohn Scipione 	BGroupView* outerControlsView = new BGroupView(B_VERTICAL);
2846048f541SJohn Scipione 	outerControlsView->GroupLayout()->SetInsets(B_USE_DEFAULT_SPACING,
2856048f541SJohn Scipione 		B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING);
286b21d610eSAxel Dörfler 	controlsBox->AddChild(outerControlsView);
287a10cf76eSAxel Dörfler 
288551c9f15SSiarzhuk Zharski 	fResolutionMenu = new BPopUpMenu("resolution", true, true);
289a10cf76eSAxel Dörfler 
29066ab1666SAxel Dörfler 	uint16 maxWidth = 0;
29166ab1666SAxel Dörfler 	uint16 maxHeight = 0;
29266ab1666SAxel Dörfler 	uint16 previousWidth = 0;
29366ab1666SAxel Dörfler 	uint16 previousHeight = 0;
294a10cf76eSAxel Dörfler 	for (int32 i = 0; i < fScreenMode.CountModes(); i++) {
295a10cf76eSAxel Dörfler 		screen_mode mode = fScreenMode.ModeAt(i);
296a10cf76eSAxel Dörfler 
297a10cf76eSAxel Dörfler 		if (mode.width == previousWidth && mode.height == previousHeight)
298a10cf76eSAxel Dörfler 			continue;
299a10cf76eSAxel Dörfler 
300a10cf76eSAxel Dörfler 		previousWidth = mode.width;
301a10cf76eSAxel Dörfler 		previousHeight = mode.height;
30266ab1666SAxel Dörfler 		if (maxWidth < mode.width)
30366ab1666SAxel Dörfler 			maxWidth = mode.width;
30466ab1666SAxel Dörfler 		if (maxHeight < mode.height)
30566ab1666SAxel Dörfler 			maxHeight = mode.height;
306a10cf76eSAxel Dörfler 
307a10cf76eSAxel Dörfler 		BMessage* message = new BMessage(POP_RESOLUTION_MSG);
308a10cf76eSAxel Dörfler 		message->AddInt32("width", mode.width);
309a10cf76eSAxel Dörfler 		message->AddInt32("height", mode.height);
310a10cf76eSAxel Dörfler 
311a10cf76eSAxel Dörfler 		BString name;
312a10cf76eSAxel Dörfler 		name << mode.width << " x " << mode.height;
313a10cf76eSAxel Dörfler 
314a10cf76eSAxel Dörfler 		fResolutionMenu->AddItem(new BMenuItem(name.String(), message));
315a10cf76eSAxel Dörfler 	}
316a10cf76eSAxel Dörfler 
31766ab1666SAxel Dörfler 	fMonitorView->SetMaxResolution(maxWidth, maxHeight);
31866ab1666SAxel Dörfler 
319c9e8f97aSAdrien Destugues 	fResolutionField = new BMenuField("ResolutionMenu",
32010dfe897SAxel Dörfler 		B_TRANSLATE("Resolution:"), fResolutionMenu);
3216048f541SJohn Scipione 	fResolutionField->SetAlignment(B_ALIGN_RIGHT);
322a10cf76eSAxel Dörfler 
323551c9f15SSiarzhuk Zharski 	fColorsMenu = new BPopUpMenu("colors", true, false);
324a10cf76eSAxel Dörfler 
325a10cf76eSAxel Dörfler 	for (int32 i = 0; i < kColorSpaceCount; i++) {
3261fc4cb1fSAxel Dörfler 		if ((fSupportedColorSpaces & (1 << i)) == 0)
3271fc4cb1fSAxel Dörfler 			continue;
3281fc4cb1fSAxel Dörfler 
329a10cf76eSAxel Dörfler 		BMessage* message = new BMessage(POP_COLORS_MSG);
330a10cf76eSAxel Dörfler 		message->AddInt32("bits_per_pixel", kColorSpaces[i].bits_per_pixel);
331a10cf76eSAxel Dörfler 		message->AddInt32("space", kColorSpaces[i].space);
332a10cf76eSAxel Dörfler 
3331fc4cb1fSAxel Dörfler 		BMenuItem* item = new BMenuItem(kColorSpaces[i].label, message);
3341fc4cb1fSAxel Dörfler 		if (kColorSpaces[i].space == screen.ColorSpace())
3351fc4cb1fSAxel Dörfler 			fUserSelectedColorSpace = item;
3361fc4cb1fSAxel Dörfler 
3371fc4cb1fSAxel Dörfler 		fColorsMenu->AddItem(item);
338a10cf76eSAxel Dörfler 	}
339a10cf76eSAxel Dörfler 
340c9e8f97aSAdrien Destugues 	fColorsField = new BMenuField("ColorsMenu", B_TRANSLATE("Colors:"),
34110dfe897SAxel Dörfler 		fColorsMenu);
3426048f541SJohn Scipione 	fColorsField->SetAlignment(B_ALIGN_RIGHT);
343a10cf76eSAxel Dörfler 
344551c9f15SSiarzhuk Zharski 	fRefreshMenu = new BPopUpMenu("refresh rate", true, true);
345a10cf76eSAxel Dörfler 
34629e8a73aSAxel Dörfler 	float min, max;
347ec495b30SRene Gollent 	if (fScreenMode.GetRefreshLimits(fActive, min, max) != B_OK) {
348ec495b30SRene Gollent 		// if we couldn't obtain the refresh limits, reset to the default
349ec495b30SRene Gollent 		// range. Constraints from detected monitors will fine-tune this
350ec495b30SRene Gollent 		// later.
351ec495b30SRene Gollent 		min = kRefreshRates[0];
352ec495b30SRene Gollent 		max = kRefreshRates[kRefreshRateCount - 1];
353ec495b30SRene Gollent 	}
354ec495b30SRene Gollent 
355ec495b30SRene Gollent 	if (min == max) {
35629e8a73aSAxel Dörfler 		// This is a special case for drivers that only support a single
35729e8a73aSAxel Dörfler 		// frequency, like the VESA driver
35829e8a73aSAxel Dörfler 		BString name;
3597e44de36SRene Gollent 		refresh_rate_to_string(min, name);
360cf076964SRene Gollent 		BMessage *message = new BMessage(POP_REFRESH_MSG);
361cf076964SRene Gollent 		message->AddFloat("refresh", min);
362cf076964SRene Gollent 		BMenuItem *item = new BMenuItem(name.String(), message);
3630efb8b66SJerome Duval 		fRefreshMenu->AddItem(item);
36429e8a73aSAxel Dörfler 		item->SetEnabled(false);
36529e8a73aSAxel Dörfler 	} else {
36670a2b1b5SAxel Dörfler 		monitor_info info;
36770a2b1b5SAxel Dörfler 		if (fScreenMode.GetMonitorInfo(info) == B_OK) {
36870a2b1b5SAxel Dörfler 			min = max_c(info.min_vertical_frequency, min);
36970a2b1b5SAxel Dörfler 			max = min_c(info.max_vertical_frequency, max);
37070a2b1b5SAxel Dörfler 		}
37170a2b1b5SAxel Dörfler 
372a10cf76eSAxel Dörfler 		for (int32 i = 0; i < kRefreshRateCount; ++i) {
37370a2b1b5SAxel Dörfler 			if (kRefreshRates[i] < min || kRefreshRates[i] > max)
37470a2b1b5SAxel Dörfler 				continue;
37570a2b1b5SAxel Dörfler 
376a10cf76eSAxel Dörfler 			BString name;
377551c9f15SSiarzhuk Zharski 			name << kRefreshRates[i] << " " << B_TRANSLATE("Hz");
378a10cf76eSAxel Dörfler 
3790efb8b66SJerome Duval 			BMessage *message = new BMessage(POP_REFRESH_MSG);
380a10cf76eSAxel Dörfler 			message->AddFloat("refresh", kRefreshRates[i]);
381a10cf76eSAxel Dörfler 
382a10cf76eSAxel Dörfler 			fRefreshMenu->AddItem(new BMenuItem(name.String(), message));
383a10cf76eSAxel Dörfler 		}
384a10cf76eSAxel Dörfler 
385c9e8f97aSAdrien Destugues 		fOtherRefresh = new BMenuItem(B_TRANSLATE("Other" B_UTF8_ELLIPSIS),
3860efb8b66SJerome Duval 			new BMessage(POP_OTHER_REFRESH_MSG));
387a10cf76eSAxel Dörfler 		fRefreshMenu->AddItem(fOtherRefresh);
38829e8a73aSAxel Dörfler 	}
389a10cf76eSAxel Dörfler 
390c9e8f97aSAdrien Destugues 	fRefreshField = new BMenuField("RefreshMenu", B_TRANSLATE("Refresh rate:"),
39110dfe897SAxel Dörfler 		fRefreshMenu);
3926048f541SJohn Scipione 	fRefreshField->SetAlignment(B_ALIGN_RIGHT);
393b21d610eSAxel Dörfler 
39412580984SAxel Dörfler 	if (_IsVesa())
39512580984SAxel Dörfler 		fRefreshField->Hide();
396a10cf76eSAxel Dörfler 
397a10cf76eSAxel Dörfler 	// enlarged area for multi-monitor settings
398a10cf76eSAxel Dörfler 	{
399a10cf76eSAxel Dörfler 		bool dummy;
400a10cf76eSAxel Dörfler 		uint32 dummy32;
401a10cf76eSAxel Dörfler 		bool multiMonSupport;
402a10cf76eSAxel Dörfler 		bool useLaptopPanelSupport;
403a10cf76eSAxel Dörfler 		bool tvStandardSupport;
404a10cf76eSAxel Dörfler 
405a10cf76eSAxel Dörfler 		multiMonSupport = TestMultiMonSupport(&screen) == B_OK;
406a10cf76eSAxel Dörfler 		useLaptopPanelSupport = GetUseLaptopPanel(&screen, &dummy) == B_OK;
407a10cf76eSAxel Dörfler 		tvStandardSupport = GetTVStandard(&screen, &dummy32) == B_OK;
408a10cf76eSAxel Dörfler 
409a10cf76eSAxel Dörfler 		// even if there is no support, we still create all controls
410a10cf76eSAxel Dörfler 		// to make sure we don't access NULL pointers later on
411a10cf76eSAxel Dörfler 
412551c9f15SSiarzhuk Zharski 		fCombineMenu = new BPopUpMenu("CombineDisplays",
413c9e8f97aSAdrien Destugues 			true, true);
414a10cf76eSAxel Dörfler 
415a10cf76eSAxel Dörfler 		for (int32 i = 0; i < kCombineModeCount; i++) {
4160efb8b66SJerome Duval 			BMessage *message = new BMessage(POP_COMBINE_DISPLAYS_MSG);
417a10cf76eSAxel Dörfler 			message->AddInt32("mode", kCombineModes[i].mode);
418a10cf76eSAxel Dörfler 
419d1516993SAxel Dörfler 			fCombineMenu->AddItem(new BMenuItem(kCombineModes[i].name,
420d1516993SAxel Dörfler 				message));
421a10cf76eSAxel Dörfler 		}
422a10cf76eSAxel Dörfler 
423b21d610eSAxel Dörfler 		fCombineField = new BMenuField("CombineMenu",
42410dfe897SAxel Dörfler 			B_TRANSLATE("Combine displays:"), fCombineMenu);
4256048f541SJohn Scipione 		fCombineField->SetAlignment(B_ALIGN_RIGHT);
426a10cf76eSAxel Dörfler 
427a10cf76eSAxel Dörfler 		if (!multiMonSupport)
428df3f5bacSStephan Aßmus 			fCombineField->Hide();
429a10cf76eSAxel Dörfler 
430551c9f15SSiarzhuk Zharski 		fSwapDisplaysMenu = new BPopUpMenu("SwapDisplays",
431c9e8f97aSAdrien Destugues 			true, true);
432a10cf76eSAxel Dörfler 
433a10cf76eSAxel Dörfler 		// !order is important - we rely that boolean value == idx
4340efb8b66SJerome Duval 		BMessage *message = new BMessage(POP_SWAP_DISPLAYS_MSG);
435a10cf76eSAxel Dörfler 		message->AddBool("swap", false);
436c9e8f97aSAdrien Destugues 		fSwapDisplaysMenu->AddItem(new BMenuItem(B_TRANSLATE("no"), message));
437a10cf76eSAxel Dörfler 
438a10cf76eSAxel Dörfler 		message = new BMessage(POP_SWAP_DISPLAYS_MSG);
439a10cf76eSAxel Dörfler 		message->AddBool("swap", true);
440c9e8f97aSAdrien Destugues 		fSwapDisplaysMenu->AddItem(new BMenuItem(B_TRANSLATE("yes"), message));
441a10cf76eSAxel Dörfler 
442c9e8f97aSAdrien Destugues 		fSwapDisplaysField = new BMenuField("SwapMenu",
44310dfe897SAxel Dörfler 			B_TRANSLATE("Swap displays:"), fSwapDisplaysMenu);
4446048f541SJohn Scipione 		fSwapDisplaysField->SetAlignment(B_ALIGN_RIGHT);
445a10cf76eSAxel Dörfler 
446a10cf76eSAxel Dörfler 		if (!multiMonSupport)
447df3f5bacSStephan Aßmus 			fSwapDisplaysField->Hide();
448a10cf76eSAxel Dörfler 
449551c9f15SSiarzhuk Zharski 		fUseLaptopPanelMenu = new BPopUpMenu("UseLaptopPanel",
450c9e8f97aSAdrien Destugues 			true, true);
451a10cf76eSAxel Dörfler 
452a10cf76eSAxel Dörfler 		// !order is important - we rely that boolean value == idx
453a10cf76eSAxel Dörfler 		message = new BMessage(POP_USE_LAPTOP_PANEL_MSG);
454a10cf76eSAxel Dörfler 		message->AddBool("use", false);
455c9e8f97aSAdrien Destugues 		fUseLaptopPanelMenu->AddItem(new BMenuItem(B_TRANSLATE("if needed"),
456c9e8f97aSAdrien Destugues 			message));
457a10cf76eSAxel Dörfler 
458a10cf76eSAxel Dörfler 		message = new BMessage(POP_USE_LAPTOP_PANEL_MSG);
459a10cf76eSAxel Dörfler 		message->AddBool("use", true);
460c9e8f97aSAdrien Destugues 		fUseLaptopPanelMenu->AddItem(new BMenuItem(B_TRANSLATE("always"),
461c9e8f97aSAdrien Destugues 			message));
462a10cf76eSAxel Dörfler 
463b21d610eSAxel Dörfler 		fUseLaptopPanelField = new BMenuField("UseLaptopPanel",
46410dfe897SAxel Dörfler 			B_TRANSLATE("Use laptop panel:"), fUseLaptopPanelMenu);
4656048f541SJohn Scipione 		fUseLaptopPanelField->SetAlignment(B_ALIGN_RIGHT);
466a10cf76eSAxel Dörfler 
467a10cf76eSAxel Dörfler 		if (!useLaptopPanelSupport)
468df3f5bacSStephan Aßmus 			fUseLaptopPanelField->Hide();
469a10cf76eSAxel Dörfler 
470551c9f15SSiarzhuk Zharski 		fTVStandardMenu = new BPopUpMenu("TVStandard", true, true);
471a10cf76eSAxel Dörfler 
472a10cf76eSAxel Dörfler 		// arbitrary limit
473a10cf76eSAxel Dörfler 		uint32 i;
474a10cf76eSAxel Dörfler 		for (i = 0; i < 100; ++i) {
475a10cf76eSAxel Dörfler 			uint32 mode;
476a10cf76eSAxel Dörfler 			if (GetNthSupportedTVStandard(&screen, i, &mode) != B_OK)
477a10cf76eSAxel Dörfler 				break;
478a10cf76eSAxel Dörfler 
479a10cf76eSAxel Dörfler 			BString name = tv_standard_to_string(mode);
480a10cf76eSAxel Dörfler 
481a10cf76eSAxel Dörfler 			message = new BMessage(POP_TV_STANDARD_MSG);
482a10cf76eSAxel Dörfler 			message->AddInt32("tv_standard", mode);
483a10cf76eSAxel Dörfler 
484a10cf76eSAxel Dörfler 			fTVStandardMenu->AddItem(new BMenuItem(name.String(), message));
485a10cf76eSAxel Dörfler 		}
486a10cf76eSAxel Dörfler 
487c9e8f97aSAdrien Destugues 		fTVStandardField = new BMenuField("tv standard",
48810dfe897SAxel Dörfler 			B_TRANSLATE("Video format:"), fTVStandardMenu);
489df3f5bacSStephan Aßmus 		fTVStandardField->SetAlignment(B_ALIGN_RIGHT);
490a10cf76eSAxel Dörfler 
491b21d610eSAxel Dörfler 		if (!tvStandardSupport || i == 0)
492df3f5bacSStephan Aßmus 			fTVStandardField->Hide();
493a10cf76eSAxel Dörfler 	}
494a10cf76eSAxel Dörfler 
49525fd5c7bSAlex Wilson 	BLayoutBuilder::Group<>(outerControlsView)
4966048f541SJohn Scipione 		.AddGrid(B_USE_DEFAULT_SPACING, B_USE_SMALL_SPACING)
4976048f541SJohn Scipione 			.Add(fResolutionField->CreateLabelLayoutItem(), 0, 0)
4986048f541SJohn Scipione 			.Add(fResolutionField->CreateMenuBarLayoutItem(), 1, 0)
4996048f541SJohn Scipione 			.Add(fColorsField->CreateLabelLayoutItem(), 0, 1)
5006048f541SJohn Scipione 			.Add(fColorsField->CreateMenuBarLayoutItem(), 1, 1)
5016048f541SJohn Scipione 			.Add(fRefreshField->CreateLabelLayoutItem(), 0, 2)
5026048f541SJohn Scipione 			.Add(fRefreshField->CreateMenuBarLayoutItem(), 1, 2)
5036048f541SJohn Scipione 			.Add(fCombineField->CreateLabelLayoutItem(), 0, 3)
5046048f541SJohn Scipione 			.Add(fCombineField->CreateMenuBarLayoutItem(), 1, 3)
5056048f541SJohn Scipione 			.Add(fSwapDisplaysField->CreateLabelLayoutItem(), 0, 4)
5066048f541SJohn Scipione 			.Add(fSwapDisplaysField->CreateMenuBarLayoutItem(), 1, 4)
5076048f541SJohn Scipione 			.Add(fUseLaptopPanelField->CreateLabelLayoutItem(), 0, 5)
5086048f541SJohn Scipione 			.Add(fUseLaptopPanelField->CreateMenuBarLayoutItem(), 1, 5)
5096048f541SJohn Scipione 			.Add(fTVStandardField->CreateLabelLayoutItem(), 0, 6)
5106048f541SJohn Scipione 			.Add(fTVStandardField->CreateMenuBarLayoutItem(), 1, 6)
51125fd5c7bSAlex Wilson 		.End();
512df3f5bacSStephan Aßmus 
513b05def65SHumdinger 	fBrightnessSlider = new BSlider("brightness", B_TRANSLATE("Brightness:"),
5143a2b67b5SAdrien Destugues 		NULL, 0, 255, B_HORIZONTAL);
5153a2b67b5SAdrien Destugues 
5163a2b67b5SAdrien Destugues 	status_t result = screen.GetBrightness(&fOriginalBrightness);
5173a2b67b5SAdrien Destugues 	if (result == B_OK) {
5183a2b67b5SAdrien Destugues 		fBrightnessSlider->SetModificationMessage(
5193a2b67b5SAdrien Destugues 			new BMessage(SLIDER_BRIGHTNESS_MSG));
5203a2b67b5SAdrien Destugues 		fBrightnessSlider->SetValue(fOriginalBrightness * 255);
5213a2b67b5SAdrien Destugues 	} else {
5223a2b67b5SAdrien Destugues 		// The driver does not support changing the brightness,
5233a2b67b5SAdrien Destugues 		// so hide the slider
5243a2b67b5SAdrien Destugues 		fBrightnessSlider->Hide();
5253a2b67b5SAdrien Destugues 
5263a2b67b5SAdrien Destugues 		fOriginalBrightness = -1;
5273a2b67b5SAdrien Destugues 	}
5283a2b67b5SAdrien Destugues 
529abc649b8SWaldemar Kornewald 	// TODO: we don't support getting the screen's preferred settings
530abc649b8SWaldemar Kornewald 	/* fDefaultsButton = new BButton(buttonRect, "DefaultsButton", "Defaults",
531b21d610eSAxel Dörfler 		new BMessage(BUTTON_DEFAULTS_MSG));*/
532a10cf76eSAxel Dörfler 
533c9e8f97aSAdrien Destugues 	fApplyButton = new BButton("ApplyButton", B_TRANSLATE("Apply"),
534df3f5bacSStephan Aßmus 		new BMessage(BUTTON_APPLY_MSG));
535df3f5bacSStephan Aßmus 	fApplyButton->SetEnabled(false);
53625fd5c7bSAlex Wilson 	BLayoutBuilder::Group<>(outerControlsView)
537b21d610eSAxel Dörfler 		.AddGlue()
53825fd5c7bSAlex Wilson 		.AddGroup(B_HORIZONTAL)
53925fd5c7bSAlex Wilson 			.AddGlue()
54025fd5c7bSAlex Wilson 			.Add(fApplyButton);
541b21d610eSAxel Dörfler 
542c9e8f97aSAdrien Destugues 	fRevertButton = new BButton("RevertButton", B_TRANSLATE("Revert"),
543b21d610eSAxel Dörfler 		new BMessage(BUTTON_REVERT_MSG));
544b21d610eSAxel Dörfler 	fRevertButton->SetEnabled(false);
545b21d610eSAxel Dörfler 
5464666484fSJohn Scipione 	BLayoutBuilder::Group<>(this, B_VERTICAL, B_USE_DEFAULT_SPACING)
5474666484fSJohn Scipione 		.AddGroup(B_HORIZONTAL)
548a2cb1737SAdrien Destugues 			.AddGroup(B_VERTICAL, 0, 1)
54983cc66b3SJohn Scipione 				.AddStrut(floorf(controlsBox->TopBorderOffset()) - 1)
550b21d610eSAxel Dörfler 				.Add(screenBox)
55183cc66b3SJohn Scipione 				.End()
5523a2b67b5SAdrien Destugues 			.AddGroup(B_VERTICAL, 0, 1)
553a2cb1737SAdrien Destugues 				.Add(controlsBox, 2)
5543a2b67b5SAdrien Destugues 				.Add(fBrightnessSlider)
5553a2b67b5SAdrien Destugues 				.End()
556b21d610eSAxel Dörfler 			.End()
5574666484fSJohn Scipione 		.AddGroup(B_HORIZONTAL, B_USE_DEFAULT_SPACING)
558b21d610eSAxel Dörfler 			.Add(fRevertButton)
5594666484fSJohn Scipione 			.AddGlue()
5604666484fSJohn Scipione 			.End()
561d0ac6099SHumdinger 		.SetInsets(B_USE_WINDOW_SPACING);
562b21d610eSAxel Dörfler 
5635de171daSAxel Dörfler 	_UpdateControls();
56412966d04SAxel Dörfler 	_UpdateMonitor();
5658bf216d6SAxel Dörfler 
5668bf216d6SAxel Dörfler 	MoveOnScreen();
567a10cf76eSAxel Dörfler }
568a10cf76eSAxel Dörfler 
569a10cf76eSAxel Dörfler 
570a10cf76eSAxel Dörfler ScreenWindow::~ScreenWindow()
571a10cf76eSAxel Dörfler {
572a10cf76eSAxel Dörfler 	delete fSettings;
573a10cf76eSAxel Dörfler }
574a10cf76eSAxel Dörfler 
575a10cf76eSAxel Dörfler 
576a10cf76eSAxel Dörfler bool
577a10cf76eSAxel Dörfler ScreenWindow::QuitRequested()
578a10cf76eSAxel Dörfler {
579a10cf76eSAxel Dörfler 	fSettings->SetWindowFrame(Frame());
580199893c3SAxel Dörfler 
581199893c3SAxel Dörfler 	// Write mode of workspace 0 (the boot workspace) to the vesa settings file
582199893c3SAxel Dörfler 	screen_mode vesaMode;
583199893c3SAxel Dörfler 	if (fBootWorkspaceApplied && fScreenMode.Get(vesaMode, 0) == B_OK) {
584199893c3SAxel Dörfler 		status_t status = _WriteVesaModeFile(vesaMode);
58512580984SAxel Dörfler 		if (status < B_OK) {
586c9e8f97aSAdrien Destugues 			BString warning = B_TRANSLATE("Could not write VESA mode settings"
587c9e8f97aSAdrien Destugues 				" file:\n\t");
58812580984SAxel Dörfler 			warning << strerror(status);
589aed35104SHumdinger 			BAlert* alert = new BAlert(B_TRANSLATE("Warning"),
590aed35104SHumdinger 				warning.String(), B_TRANSLATE("OK"), NULL,
591aed35104SHumdinger 				NULL, B_WIDTH_AS_USUAL, B_WARNING_ALERT);
592aed35104SHumdinger 			alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE);
593aed35104SHumdinger 			alert->Go();
59412580984SAxel Dörfler 		}
59512580984SAxel Dörfler 	}
59612580984SAxel Dörfler 
597a10cf76eSAxel Dörfler 	be_app->PostMessage(B_QUIT_REQUESTED);
598a10cf76eSAxel Dörfler 
599a10cf76eSAxel Dörfler 	return BWindow::QuitRequested();
600a10cf76eSAxel Dörfler }
601a10cf76eSAxel Dörfler 
602a10cf76eSAxel Dörfler 
6035de171daSAxel Dörfler /*!	Update resolution list according to combine mode
6041fc4cb1fSAxel Dörfler 	(some resolutions may not be combinable due to memory restrictions).
605a10cf76eSAxel Dörfler */
606a10cf76eSAxel Dörfler void
6075de171daSAxel Dörfler ScreenWindow::_CheckResolutionMenu()
608a10cf76eSAxel Dörfler {
609a10cf76eSAxel Dörfler 	for (int32 i = 0; i < fResolutionMenu->CountItems(); i++)
610a10cf76eSAxel Dörfler 		fResolutionMenu->ItemAt(i)->SetEnabled(false);
611a10cf76eSAxel Dörfler 
612a10cf76eSAxel Dörfler 	for (int32 i = 0; i < fScreenMode.CountModes(); i++) {
613a10cf76eSAxel Dörfler 		screen_mode mode = fScreenMode.ModeAt(i);
614a10cf76eSAxel Dörfler 		if (mode.combine != fSelected.combine)
615a10cf76eSAxel Dörfler 			continue;
616a10cf76eSAxel Dörfler 
617a10cf76eSAxel Dörfler 		BString name;
618a10cf76eSAxel Dörfler 		name << mode.width << " x " << mode.height;
619a10cf76eSAxel Dörfler 
620a10cf76eSAxel Dörfler 		BMenuItem *item = fResolutionMenu->FindItem(name.String());
621a10cf76eSAxel Dörfler 		if (item != NULL)
622a10cf76eSAxel Dörfler 			item->SetEnabled(true);
623a10cf76eSAxel Dörfler 	}
624a10cf76eSAxel Dörfler }
625a10cf76eSAxel Dörfler 
626a10cf76eSAxel Dörfler 
6275de171daSAxel Dörfler /*!	Update color and refresh options according to current mode
6285de171daSAxel Dörfler 	(a color space is made active if there is any mode with
6295de171daSAxel Dörfler 	given resolution and this colour space; same applies for
6305de171daSAxel Dörfler 	refresh rate, though "Other…" is always possible)
631a10cf76eSAxel Dörfler */
632a10cf76eSAxel Dörfler void
6335de171daSAxel Dörfler ScreenWindow::_CheckColorMenu()
634a10cf76eSAxel Dörfler {
6351fc4cb1fSAxel Dörfler 	int32 supportsAnything = false;
6361fc4cb1fSAxel Dörfler 	int32 index = 0;
6371fc4cb1fSAxel Dörfler 
638a10cf76eSAxel Dörfler 	for (int32 i = 0; i < kColorSpaceCount; i++) {
6391fc4cb1fSAxel Dörfler 		if ((fSupportedColorSpaces & (1 << i)) == 0)
6401fc4cb1fSAxel Dörfler 			continue;
6411fc4cb1fSAxel Dörfler 
642a10cf76eSAxel Dörfler 		bool supported = false;
643a10cf76eSAxel Dörfler 
644a10cf76eSAxel Dörfler 		for (int32 j = 0; j < fScreenMode.CountModes(); j++) {
645a10cf76eSAxel Dörfler 			screen_mode mode = fScreenMode.ModeAt(j);
646a10cf76eSAxel Dörfler 
647a10cf76eSAxel Dörfler 			if (fSelected.width == mode.width
648a10cf76eSAxel Dörfler 				&& fSelected.height == mode.height
6491fc4cb1fSAxel Dörfler 				&& kColorSpaces[i].space == mode.space
650a10cf76eSAxel Dörfler 				&& fSelected.combine == mode.combine) {
6511fc4cb1fSAxel Dörfler 				supportsAnything = true;
652a10cf76eSAxel Dörfler 				supported = true;
653a10cf76eSAxel Dörfler 				break;
654a10cf76eSAxel Dörfler 			}
655a10cf76eSAxel Dörfler 		}
656a10cf76eSAxel Dörfler 
6571fc4cb1fSAxel Dörfler 		BMenuItem* item = fColorsMenu->ItemAt(index++);
658a10cf76eSAxel Dörfler 		if (item)
659a10cf76eSAxel Dörfler 			item->SetEnabled(supported);
660a10cf76eSAxel Dörfler 	}
6611fc4cb1fSAxel Dörfler 
6621fc4cb1fSAxel Dörfler 	fColorsField->SetEnabled(supportsAnything);
6631fc4cb1fSAxel Dörfler 
6641fc4cb1fSAxel Dörfler 	if (!supportsAnything)
6651fc4cb1fSAxel Dörfler 		return;
6661fc4cb1fSAxel Dörfler 
6671fc4cb1fSAxel Dörfler 	// Make sure a valid item is selected
6681fc4cb1fSAxel Dörfler 
6691fc4cb1fSAxel Dörfler 	BMenuItem* item = fColorsMenu->FindMarked();
6701fc4cb1fSAxel Dörfler 	bool changed = false;
6711fc4cb1fSAxel Dörfler 
6721fc4cb1fSAxel Dörfler 	if (item != fUserSelectedColorSpace) {
6731fc4cb1fSAxel Dörfler 		if (fUserSelectedColorSpace != NULL
6741fc4cb1fSAxel Dörfler 			&& fUserSelectedColorSpace->IsEnabled()) {
6751fc4cb1fSAxel Dörfler 			fUserSelectedColorSpace->SetMarked(true);
6761fc4cb1fSAxel Dörfler 			item = fUserSelectedColorSpace;
6771fc4cb1fSAxel Dörfler 			changed = true;
6781fc4cb1fSAxel Dörfler 		}
6791fc4cb1fSAxel Dörfler 	}
6801fc4cb1fSAxel Dörfler 	if (item != NULL && !item->IsEnabled()) {
6811fc4cb1fSAxel Dörfler 		// find the next best item
6821fc4cb1fSAxel Dörfler 		int32 index = fColorsMenu->IndexOf(item);
6831fc4cb1fSAxel Dörfler 		bool found = false;
6841fc4cb1fSAxel Dörfler 
6851fc4cb1fSAxel Dörfler 		for (int32 i = index + 1; i < fColorsMenu->CountItems(); i++) {
6861fc4cb1fSAxel Dörfler 			item = fColorsMenu->ItemAt(i);
6871fc4cb1fSAxel Dörfler 			if (item->IsEnabled()) {
6881fc4cb1fSAxel Dörfler 				found = true;
6891fc4cb1fSAxel Dörfler 				break;
6901fc4cb1fSAxel Dörfler 			}
6911fc4cb1fSAxel Dörfler 		}
6921fc4cb1fSAxel Dörfler 		if (!found) {
6931fc4cb1fSAxel Dörfler 			// search backwards as well
6941fc4cb1fSAxel Dörfler 			for (int32 i = index - 1; i >= 0; i--) {
6951fc4cb1fSAxel Dörfler 				item = fColorsMenu->ItemAt(i);
6961fc4cb1fSAxel Dörfler 				if (item->IsEnabled())
6971fc4cb1fSAxel Dörfler 					break;
6981fc4cb1fSAxel Dörfler 			}
6991fc4cb1fSAxel Dörfler 		}
7001fc4cb1fSAxel Dörfler 
7011fc4cb1fSAxel Dörfler 		item->SetMarked(true);
7021fc4cb1fSAxel Dörfler 		changed = true;
7031fc4cb1fSAxel Dörfler 	}
7041fc4cb1fSAxel Dörfler 
7051fc4cb1fSAxel Dörfler 	if (changed) {
7061fc4cb1fSAxel Dörfler 		// Update selected space
7071fc4cb1fSAxel Dörfler 
7081fc4cb1fSAxel Dörfler 		BMessage* message = item->Message();
7091fc4cb1fSAxel Dörfler 		int32 space;
7101fc4cb1fSAxel Dörfler 		if (message->FindInt32("space", &space) == B_OK) {
7111fc4cb1fSAxel Dörfler 			fSelected.space = (color_space)space;
7121fc4cb1fSAxel Dörfler 			_UpdateColorLabel();
7131fc4cb1fSAxel Dörfler 		}
7141fc4cb1fSAxel Dörfler 	}
715a10cf76eSAxel Dörfler }
716a10cf76eSAxel Dörfler 
717a10cf76eSAxel Dörfler 
7185de171daSAxel Dörfler /*!	Enable/disable refresh options according to current mode. */
719a10cf76eSAxel Dörfler void
7205de171daSAxel Dörfler ScreenWindow::_CheckRefreshMenu()
721a10cf76eSAxel Dörfler {
72229e8a73aSAxel Dörfler 	float min, max;
72329e8a73aSAxel Dörfler 	if (fScreenMode.GetRefreshLimits(fSelected, min, max) != B_OK || min == max)
72429e8a73aSAxel Dörfler 		return;
725a10cf76eSAxel Dörfler 
72629e8a73aSAxel Dörfler 	for (int32 i = fRefreshMenu->CountItems(); i-- > 0;) {
72729e8a73aSAxel Dörfler 		BMenuItem* item = fRefreshMenu->ItemAt(i);
72829e8a73aSAxel Dörfler 		BMessage* message = item->Message();
72929e8a73aSAxel Dörfler 		float refresh;
73029e8a73aSAxel Dörfler 		if (message != NULL && message->FindFloat("refresh", &refresh) == B_OK)
73129e8a73aSAxel Dörfler 			item->SetEnabled(refresh >= min && refresh <= max);
732a10cf76eSAxel Dörfler 	}
733a10cf76eSAxel Dörfler }
734a10cf76eSAxel Dörfler 
735a10cf76eSAxel Dörfler 
7365de171daSAxel Dörfler /*!	Activate appropriate menu item according to selected refresh rate */
737a10cf76eSAxel Dörfler void
7385de171daSAxel Dörfler ScreenWindow::_UpdateRefreshControl()
739a10cf76eSAxel Dörfler {
7407e44de36SRene Gollent 	for (int32 i = 0; i < fRefreshMenu->CountItems(); i++) {
7417e44de36SRene Gollent 		BMenuItem* item = fRefreshMenu->ItemAt(i);
7427e44de36SRene Gollent 		if (item->Message()->FindFloat("refresh") == fSelected.refresh) {
743a10cf76eSAxel Dörfler 			item->SetMarked(true);
74426747978SAdrien Destugues 			// "Other" items only contains a refresh rate when active
745122d4ef7SMurai Takashi 			if (fOtherRefresh != NULL)
74626747978SAdrien Destugues 				fOtherRefresh->SetLabel(B_TRANSLATE("Other" B_UTF8_ELLIPSIS));
747a10cf76eSAxel Dörfler 			return;
748a10cf76eSAxel Dörfler 		}
7497e44de36SRene Gollent 	}
750a10cf76eSAxel Dörfler 
751a10cf76eSAxel Dörfler 	// this is a non-standard refresh rate
7527e44de36SRene Gollent 	if (fOtherRefresh != NULL) {
753a10cf76eSAxel Dörfler 		fOtherRefresh->Message()->ReplaceFloat("refresh", fSelected.refresh);
754a10cf76eSAxel Dörfler 		fOtherRefresh->SetMarked(true);
755a10cf76eSAxel Dörfler 
7567e44de36SRene Gollent 		BString string;
7577e44de36SRene Gollent 		refresh_rate_to_string(fSelected.refresh, string);
758a10cf76eSAxel Dörfler 		fRefreshMenu->Superitem()->SetLabel(string.String());
759a10cf76eSAxel Dörfler 
760c9e8f97aSAdrien Destugues 		string.Append(B_TRANSLATE("/other" B_UTF8_ELLIPSIS));
761a10cf76eSAxel Dörfler 		fOtherRefresh->SetLabel(string.String());
762a10cf76eSAxel Dörfler 	}
7637e44de36SRene Gollent }
764a10cf76eSAxel Dörfler 
765a10cf76eSAxel Dörfler 
766a10cf76eSAxel Dörfler void
7675de171daSAxel Dörfler ScreenWindow::_UpdateMonitorView()
768a10cf76eSAxel Dörfler {
769a10cf76eSAxel Dörfler 	BMessage updateMessage(UPDATE_DESKTOP_MSG);
770a10cf76eSAxel Dörfler 	updateMessage.AddInt32("width", fSelected.width);
771a10cf76eSAxel Dörfler 	updateMessage.AddInt32("height", fSelected.height);
772a10cf76eSAxel Dörfler 
773a10cf76eSAxel Dörfler 	PostMessage(&updateMessage, fMonitorView);
774a10cf76eSAxel Dörfler }
775a10cf76eSAxel Dörfler 
776a10cf76eSAxel Dörfler 
777a10cf76eSAxel Dörfler void
7785de171daSAxel Dörfler ScreenWindow::_UpdateControls()
779a10cf76eSAxel Dörfler {
780b21d610eSAxel Dörfler 	_UpdateWorkspaceButtons();
781b21d610eSAxel Dörfler 
782a10cf76eSAxel Dörfler 	BMenuItem* item = fSwapDisplaysMenu->ItemAt((int32)fSelected.swap_displays);
783c33a865cSJohn Scipione 	if (item != NULL && !item->IsMarked())
784a10cf76eSAxel Dörfler 		item->SetMarked(true);
785a10cf76eSAxel Dörfler 
786a10cf76eSAxel Dörfler 	item = fUseLaptopPanelMenu->ItemAt((int32)fSelected.use_laptop_panel);
787c33a865cSJohn Scipione 	if (item != NULL && !item->IsMarked())
788a10cf76eSAxel Dörfler 		item->SetMarked(true);
789a10cf76eSAxel Dörfler 
790a10cf76eSAxel Dörfler 	for (int32 i = 0; i < fTVStandardMenu->CountItems(); i++) {
791a10cf76eSAxel Dörfler 		item = fTVStandardMenu->ItemAt(i);
792a10cf76eSAxel Dörfler 
793a10cf76eSAxel Dörfler 		uint32 tvStandard;
794a10cf76eSAxel Dörfler 		item->Message()->FindInt32("tv_standard", (int32 *)&tvStandard);
795a10cf76eSAxel Dörfler 		if (tvStandard == fSelected.tv_standard) {
796a10cf76eSAxel Dörfler 			if (!item->IsMarked())
797a10cf76eSAxel Dörfler 				item->SetMarked(true);
798a10cf76eSAxel Dörfler 			break;
799a10cf76eSAxel Dörfler 		}
800a10cf76eSAxel Dörfler 	}
801a10cf76eSAxel Dörfler 
8025de171daSAxel Dörfler 	_CheckResolutionMenu();
8035de171daSAxel Dörfler 	_CheckColorMenu();
8045de171daSAxel Dörfler 	_CheckRefreshMenu();
805a10cf76eSAxel Dörfler 
806a10cf76eSAxel Dörfler 	BString string;
807a10cf76eSAxel Dörfler 	resolution_to_string(fSelected, string);
808a10cf76eSAxel Dörfler 	item = fResolutionMenu->FindItem(string.String());
809a10cf76eSAxel Dörfler 
810a10cf76eSAxel Dörfler 	if (item != NULL) {
811a10cf76eSAxel Dörfler 		if (!item->IsMarked())
812a10cf76eSAxel Dörfler 			item->SetMarked(true);
813a10cf76eSAxel Dörfler 	} else {
814a10cf76eSAxel Dörfler 		// this is bad luck - if mode has been set via screen references,
815a10cf76eSAxel Dörfler 		// this case cannot occur; there are three possible solutions:
816a10cf76eSAxel Dörfler 		// 1. add a new resolution to list
817a10cf76eSAxel Dörfler 		//    - we had to remove it as soon as a "valid" one is selected
818a10cf76eSAxel Dörfler 		//    - we don't know which frequencies/bit depths are supported
819a10cf76eSAxel Dörfler 		//    - as long as we haven't the GMT formula to create
820a10cf76eSAxel Dörfler 		//      parameters for any resolution given, we cannot
821a10cf76eSAxel Dörfler 		//      really set current mode - it's just not in the list
822a10cf76eSAxel Dörfler 		// 2. choose nearest resolution
823a10cf76eSAxel Dörfler 		//    - probably a good idea, but implies coding and testing
824a10cf76eSAxel Dörfler 		// 3. choose lowest resolution
825a10cf76eSAxel Dörfler 		//    - do you really think we are so lazy? yes, we are
826a10cf76eSAxel Dörfler 		item = fResolutionMenu->ItemAt(0);
827a10cf76eSAxel Dörfler 		if (item)
828a10cf76eSAxel Dörfler 			item->SetMarked(true);
829a10cf76eSAxel Dörfler 
830a10cf76eSAxel Dörfler 		// okay - at least we set menu label to active resolution
831a10cf76eSAxel Dörfler 		fResolutionMenu->Superitem()->SetLabel(string.String());
832a10cf76eSAxel Dörfler 	}
833a10cf76eSAxel Dörfler 
834a10cf76eSAxel Dörfler 	// mark active combine mode
835a10cf76eSAxel Dörfler 	for (int32 i = 0; i < kCombineModeCount; i++) {
836a10cf76eSAxel Dörfler 		if (kCombineModes[i].mode == fSelected.combine) {
837a10cf76eSAxel Dörfler 			item = fCombineMenu->ItemAt(i);
838c33a865cSJohn Scipione 			if (item != NULL && !item->IsMarked())
839a10cf76eSAxel Dörfler 				item->SetMarked(true);
840a10cf76eSAxel Dörfler 			break;
841a10cf76eSAxel Dörfler 		}
842a10cf76eSAxel Dörfler 	}
843a10cf76eSAxel Dörfler 
844a10cf76eSAxel Dörfler 	item = fColorsMenu->ItemAt(0);
845a10cf76eSAxel Dörfler 
8461fc4cb1fSAxel Dörfler 	for (int32 i = 0, index = 0; i <  kColorSpaceCount; i++) {
8471fc4cb1fSAxel Dörfler 		if ((fSupportedColorSpaces & (1 << i)) == 0)
8481fc4cb1fSAxel Dörfler 			continue;
8491fc4cb1fSAxel Dörfler 
8501fc4cb1fSAxel Dörfler 		if (kColorSpaces[i].space == fSelected.space) {
8511fc4cb1fSAxel Dörfler 			item = fColorsMenu->ItemAt(index);
852a10cf76eSAxel Dörfler 			break;
853a10cf76eSAxel Dörfler 		}
8541fc4cb1fSAxel Dörfler 
8551fc4cb1fSAxel Dörfler 		index++;
856a10cf76eSAxel Dörfler 	}
857a10cf76eSAxel Dörfler 
858c33a865cSJohn Scipione 	if (item != NULL && !item->IsMarked())
859a10cf76eSAxel Dörfler 		item->SetMarked(true);
860a10cf76eSAxel Dörfler 
8611fc4cb1fSAxel Dörfler 	_UpdateColorLabel();
8625de171daSAxel Dörfler 	_UpdateMonitorView();
8635de171daSAxel Dörfler 	_UpdateRefreshControl();
864a10cf76eSAxel Dörfler 
8655de171daSAxel Dörfler 	_CheckApplyEnabled();
866a10cf76eSAxel Dörfler }
867a10cf76eSAxel Dörfler 
868a10cf76eSAxel Dörfler 
86912580984SAxel Dörfler /*! Reflect active mode in chosen settings */
870a10cf76eSAxel Dörfler void
8715de171daSAxel Dörfler ScreenWindow::_UpdateActiveMode()
872a10cf76eSAxel Dörfler {
873c491b5adSJohn Scipione 	_UpdateActiveMode(current_workspace());
874c491b5adSJohn Scipione }
875c491b5adSJohn Scipione 
876c491b5adSJohn Scipione 
877c491b5adSJohn Scipione void
878c491b5adSJohn Scipione ScreenWindow::_UpdateActiveMode(int32 workspace)
879c491b5adSJohn Scipione {
88012580984SAxel Dörfler 	// Usually, this function gets called after a mode
881a10cf76eSAxel Dörfler 	// has been set manually; still, as the graphics driver
882a10cf76eSAxel Dörfler 	// is free to fiddle with mode passed, we better ask
883a10cf76eSAxel Dörfler 	// what kind of mode we actually got
884c491b5adSJohn Scipione 	if (fScreenMode.Get(fActive, workspace) == B_OK) {
885a10cf76eSAxel Dörfler 		fSelected = fActive;
886a10cf76eSAxel Dörfler 
88712966d04SAxel Dörfler 		_UpdateMonitor();
888c491b5adSJohn Scipione 		_BuildSupportedColorSpaces();
8895de171daSAxel Dörfler 		_UpdateControls();
890a10cf76eSAxel Dörfler 	}
891c491b5adSJohn Scipione }
892a10cf76eSAxel Dörfler 
893a10cf76eSAxel Dörfler 
894a10cf76eSAxel Dörfler void
895b21d610eSAxel Dörfler ScreenWindow::_UpdateWorkspaceButtons()
896b21d610eSAxel Dörfler {
897b21d610eSAxel Dörfler 	uint32 columns;
898b21d610eSAxel Dörfler 	uint32 rows;
899b21d610eSAxel Dörfler 	BPrivate::get_workspaces_layout(&columns, &rows);
900b21d610eSAxel Dörfler 
901a3fa81bdSJohn Scipione 	// Set the max values enabling/disabling the up/down arrows
902b21d610eSAxel Dörfler 
903a3fa81bdSJohn Scipione 	if (rows == 1)
904a3fa81bdSJohn Scipione 		fColumnsControl->SetMaxValue(32);
905a3fa81bdSJohn Scipione 	else if (rows == 2)
906a3fa81bdSJohn Scipione 		fColumnsControl->SetMaxValue(16);
907a3fa81bdSJohn Scipione 	else if (rows <= 4)
908a3fa81bdSJohn Scipione 		fColumnsControl->SetMaxValue(8);
909a3fa81bdSJohn Scipione 	else if (rows <= 8)
910a3fa81bdSJohn Scipione 		fColumnsControl->SetMaxValue(4);
911a3fa81bdSJohn Scipione 	else if (rows <= 16)
912a3fa81bdSJohn Scipione 		fColumnsControl->SetMaxValue(2);
913a3fa81bdSJohn Scipione 	else if (rows <= 32)
914a3fa81bdSJohn Scipione 		fColumnsControl->SetMaxValue(1);
915b21d610eSAxel Dörfler 
916a3fa81bdSJohn Scipione 	if (columns == 1)
917a3fa81bdSJohn Scipione 		fRowsControl->SetMaxValue(32);
918a3fa81bdSJohn Scipione 	else if (columns == 2)
919a3fa81bdSJohn Scipione 		fRowsControl->SetMaxValue(16);
920a3fa81bdSJohn Scipione 	else if (columns <= 4)
921a3fa81bdSJohn Scipione 		fRowsControl->SetMaxValue(8);
922a3fa81bdSJohn Scipione 	else if (columns <= 8)
923a3fa81bdSJohn Scipione 		fRowsControl->SetMaxValue(4);
924a3fa81bdSJohn Scipione 	else if (columns <= 16)
925a3fa81bdSJohn Scipione 		fRowsControl->SetMaxValue(2);
926a3fa81bdSJohn Scipione 	else if (columns <= 32)
927a3fa81bdSJohn Scipione 		fRowsControl->SetMaxValue(1);
928b21d610eSAxel Dörfler }
929b21d610eSAxel Dörfler 
930b21d610eSAxel Dörfler 
931b21d610eSAxel Dörfler void
932a10cf76eSAxel Dörfler ScreenWindow::ScreenChanged(BRect frame, color_space mode)
933a10cf76eSAxel Dörfler {
934a10cf76eSAxel Dörfler 	// move window on screen, if necessary
935a10cf76eSAxel Dörfler 	if (frame.right <= Frame().right
936a10cf76eSAxel Dörfler 		&& frame.bottom <= Frame().bottom) {
937a10cf76eSAxel Dörfler 		MoveTo((frame.Width() - Frame().Width()) / 2,
938a10cf76eSAxel Dörfler 			(frame.Height() - Frame().Height()) / 2);
939a10cf76eSAxel Dörfler 	}
940a10cf76eSAxel Dörfler }
941a10cf76eSAxel Dörfler 
942a10cf76eSAxel Dörfler 
943a10cf76eSAxel Dörfler void
944a10cf76eSAxel Dörfler ScreenWindow::WorkspaceActivated(int32 workspace, bool state)
945a10cf76eSAxel Dörfler {
946c491b5adSJohn Scipione 	if (fScreenMode.GetOriginalMode(fOriginal, workspace) == B_OK) {
947c491b5adSJohn Scipione 		_UpdateActiveMode(workspace);
948a10cf76eSAxel Dörfler 
9496edaa0f6SStefano Ceccherini 		BMessage message(UPDATE_DESKTOP_COLOR_MSG);
9506edaa0f6SStefano Ceccherini 		PostMessage(&message, fMonitorView);
951a10cf76eSAxel Dörfler 	}
952c491b5adSJohn Scipione }
953a10cf76eSAxel Dörfler 
954a10cf76eSAxel Dörfler 
955a10cf76eSAxel Dörfler void
956a10cf76eSAxel Dörfler ScreenWindow::MessageReceived(BMessage* message)
957a10cf76eSAxel Dörfler {
958a10cf76eSAxel Dörfler 	switch (message->what) {
959a10cf76eSAxel Dörfler 		case WORKSPACE_CHECK_MSG:
9605de171daSAxel Dörfler 			_CheckApplyEnabled();
961a10cf76eSAxel Dörfler 			break;
962a10cf76eSAxel Dörfler 
963b21d610eSAxel Dörfler 		case kMsgWorkspaceColumnsChanged:
964b21d610eSAxel Dörfler 		{
965a3fa81bdSJohn Scipione 			uint32 newColumns = (uint32)fColumnsControl->Value();
966b21d610eSAxel Dörfler 
967b21d610eSAxel Dörfler 			uint32 rows;
968b21d610eSAxel Dörfler 			BPrivate::get_workspaces_layout(NULL, &rows);
969b21d610eSAxel Dörfler 			BPrivate::set_workspaces_layout(newColumns, rows);
970b21d610eSAxel Dörfler 
971b21d610eSAxel Dörfler 			_UpdateWorkspaceButtons();
972a3fa81bdSJohn Scipione 			fRowsControl->SetValue(rows);
973a3fa81bdSJohn Scipione 				// enables/disables up/down arrows
974b21d610eSAxel Dörfler 			_CheckApplyEnabled();
975a3fa81bdSJohn Scipione 
976b21d610eSAxel Dörfler 			break;
977b21d610eSAxel Dörfler 		}
978b21d610eSAxel Dörfler 
979b21d610eSAxel Dörfler 		case kMsgWorkspaceRowsChanged:
980b21d610eSAxel Dörfler 		{
981a3fa81bdSJohn Scipione 			uint32 newRows = (uint32)fRowsControl->Value();
982b21d610eSAxel Dörfler 
983b21d610eSAxel Dörfler 			uint32 columns;
984b21d610eSAxel Dörfler 			BPrivate::get_workspaces_layout(&columns, NULL);
985b21d610eSAxel Dörfler 			BPrivate::set_workspaces_layout(columns, newRows);
986b21d610eSAxel Dörfler 
987b21d610eSAxel Dörfler 			_UpdateWorkspaceButtons();
988a3fa81bdSJohn Scipione 			fColumnsControl->SetValue(columns);
989a3fa81bdSJohn Scipione 				// enables/disables up/down arrows
990b21d610eSAxel Dörfler 			_CheckApplyEnabled();
991a10cf76eSAxel Dörfler 			break;
992a10cf76eSAxel Dörfler 		}
993a10cf76eSAxel Dörfler 
994a10cf76eSAxel Dörfler 		case POP_RESOLUTION_MSG:
995a10cf76eSAxel Dörfler 		{
996a10cf76eSAxel Dörfler 			message->FindInt32("width", &fSelected.width);
997a10cf76eSAxel Dörfler 			message->FindInt32("height", &fSelected.height);
998a10cf76eSAxel Dörfler 
9995de171daSAxel Dörfler 			_CheckColorMenu();
10005de171daSAxel Dörfler 			_CheckRefreshMenu();
1001a10cf76eSAxel Dörfler 
10025de171daSAxel Dörfler 			_UpdateMonitorView();
10035de171daSAxel Dörfler 			_UpdateRefreshControl();
1004a10cf76eSAxel Dörfler 
10055de171daSAxel Dörfler 			_CheckApplyEnabled();
1006a10cf76eSAxel Dörfler 			break;
1007a10cf76eSAxel Dörfler 		}
1008a10cf76eSAxel Dörfler 
1009a10cf76eSAxel Dörfler 		case POP_COLORS_MSG:
1010a10cf76eSAxel Dörfler 		{
10111fc4cb1fSAxel Dörfler 			int32 space;
10121fc4cb1fSAxel Dörfler 			if (message->FindInt32("space", &space) != B_OK)
10131fc4cb1fSAxel Dörfler 				break;
1014a10cf76eSAxel Dörfler 
10151fc4cb1fSAxel Dörfler 			int32 index;
10161fc4cb1fSAxel Dörfler 			if (message->FindInt32("index", &index) == B_OK
10171fc4cb1fSAxel Dörfler 				&& fColorsMenu->ItemAt(index) != NULL)
10181fc4cb1fSAxel Dörfler 				fUserSelectedColorSpace = fColorsMenu->ItemAt(index);
10191fc4cb1fSAxel Dörfler 
10201fc4cb1fSAxel Dörfler 			fSelected.space = (color_space)space;
10211fc4cb1fSAxel Dörfler 			_UpdateColorLabel();
1022a10cf76eSAxel Dörfler 
10235de171daSAxel Dörfler 			_CheckApplyEnabled();
1024a10cf76eSAxel Dörfler 			break;
1025a10cf76eSAxel Dörfler 		}
1026a10cf76eSAxel Dörfler 
1027a10cf76eSAxel Dörfler 		case POP_REFRESH_MSG:
1028a40498e2SWaldemar Kornewald 		{
1029a10cf76eSAxel Dörfler 			message->FindFloat("refresh", &fSelected.refresh);
1030c9e8f97aSAdrien Destugues 			fOtherRefresh->SetLabel(B_TRANSLATE("Other" B_UTF8_ELLIPSIS));
10311fc4cb1fSAxel Dörfler 				// revert "Other…" label - it might have a refresh rate prefix
1032a10cf76eSAxel Dörfler 
10335de171daSAxel Dörfler 			_CheckApplyEnabled();
1034a10cf76eSAxel Dörfler 			break;
1035a40498e2SWaldemar Kornewald 		}
1036a10cf76eSAxel Dörfler 
1037a10cf76eSAxel Dörfler 		case POP_OTHER_REFRESH_MSG:
1038a10cf76eSAxel Dörfler 		{
103929e8a73aSAxel Dörfler 			// make sure menu shows something useful
10405de171daSAxel Dörfler 			_UpdateRefreshControl();
1041a10cf76eSAxel Dörfler 
104229e8a73aSAxel Dörfler 			float min = 0, max = 999;
104329e8a73aSAxel Dörfler 			fScreenMode.GetRefreshLimits(fSelected, min, max);
104429e8a73aSAxel Dörfler 			if (min < gMinRefresh)
104529e8a73aSAxel Dörfler 				min = gMinRefresh;
104629e8a73aSAxel Dörfler 			if (max > gMaxRefresh)
104729e8a73aSAxel Dörfler 				max = gMaxRefresh;
104829e8a73aSAxel Dörfler 
104970a2b1b5SAxel Dörfler 			monitor_info info;
105070a2b1b5SAxel Dörfler 			if (fScreenMode.GetMonitorInfo(info) == B_OK) {
105170a2b1b5SAxel Dörfler 				min = max_c(info.min_vertical_frequency, min);
105270a2b1b5SAxel Dörfler 				max = min_c(info.max_vertical_frequency, max);
105370a2b1b5SAxel Dörfler 			}
105470a2b1b5SAxel Dörfler 
1055c5d10f7aSAxel Dörfler 			RefreshWindow *fRefreshWindow = new RefreshWindow(
105670a2b1b5SAxel Dörfler 				fRefreshField->ConvertToScreen(B_ORIGIN), fSelected.refresh,
105770a2b1b5SAxel Dörfler 				min, max);
1058a10cf76eSAxel Dörfler 			fRefreshWindow->Show();
1059a10cf76eSAxel Dörfler 			break;
1060a10cf76eSAxel Dörfler 		}
1061a10cf76eSAxel Dörfler 
1062a10cf76eSAxel Dörfler 		case SET_CUSTOM_REFRESH_MSG:
1063a10cf76eSAxel Dörfler 		{
1064a10cf76eSAxel Dörfler 			// user pressed "done" in "Other…" refresh dialog;
1065a10cf76eSAxel Dörfler 			// select the refresh rate chosen
1066a10cf76eSAxel Dörfler 			message->FindFloat("refresh", &fSelected.refresh);
1067a10cf76eSAxel Dörfler 
10685de171daSAxel Dörfler 			_UpdateRefreshControl();
10695de171daSAxel Dörfler 			_CheckApplyEnabled();
1070a10cf76eSAxel Dörfler 			break;
1071a10cf76eSAxel Dörfler 		}
1072a10cf76eSAxel Dörfler 
1073a10cf76eSAxel Dörfler 		case POP_COMBINE_DISPLAYS_MSG:
1074a10cf76eSAxel Dörfler 		{
1075a10cf76eSAxel Dörfler 			// new combine mode has bee chosen
1076a10cf76eSAxel Dörfler 			int32 mode;
1077a10cf76eSAxel Dörfler 			if (message->FindInt32("mode", &mode) == B_OK)
1078a10cf76eSAxel Dörfler 				fSelected.combine = (combine_mode)mode;
1079a10cf76eSAxel Dörfler 
10805de171daSAxel Dörfler 			_CheckResolutionMenu();
10815de171daSAxel Dörfler 			_CheckApplyEnabled();
1082a10cf76eSAxel Dörfler 			break;
1083a10cf76eSAxel Dörfler 		}
1084a10cf76eSAxel Dörfler 
1085a10cf76eSAxel Dörfler 		case POP_SWAP_DISPLAYS_MSG:
1086a10cf76eSAxel Dörfler 			message->FindBool("swap", &fSelected.swap_displays);
10875de171daSAxel Dörfler 			_CheckApplyEnabled();
1088a10cf76eSAxel Dörfler 			break;
1089a10cf76eSAxel Dörfler 
1090a10cf76eSAxel Dörfler 		case POP_USE_LAPTOP_PANEL_MSG:
1091a10cf76eSAxel Dörfler 			message->FindBool("use", &fSelected.use_laptop_panel);
10925de171daSAxel Dörfler 			_CheckApplyEnabled();
1093a10cf76eSAxel Dörfler 			break;
1094a10cf76eSAxel Dörfler 
1095a10cf76eSAxel Dörfler 		case POP_TV_STANDARD_MSG:
1096a10cf76eSAxel Dörfler 			message->FindInt32("tv_standard", (int32 *)&fSelected.tv_standard);
10975de171daSAxel Dörfler 			_CheckApplyEnabled();
1098a10cf76eSAxel Dörfler 			break;
1099a10cf76eSAxel Dörfler 
1100df3f5bacSStephan Aßmus 		case BUTTON_LAUNCH_BACKGROUNDS_MSG:
11016f095d6aSRyan Leavengood 			if (be_roster->Launch(kBackgroundsSignature) == B_ALREADY_RUNNING) {
11026f095d6aSRyan Leavengood 				app_info info;
11036f095d6aSRyan Leavengood 				be_roster->GetAppInfo(kBackgroundsSignature, &info);
11046f095d6aSRyan Leavengood 				be_roster->ActivateApp(info.team);
11056f095d6aSRyan Leavengood 			}
1106df3f5bacSStephan Aßmus 			break;
1107df3f5bacSStephan Aßmus 
1108a10cf76eSAxel Dörfler 		case BUTTON_DEFAULTS_MSG:
1109a10cf76eSAxel Dörfler 		{
11104be51fe3SWaldemar Kornewald 			// TODO: get preferred settings of screen
1111a10cf76eSAxel Dörfler 			fSelected.width = 640;
1112a10cf76eSAxel Dörfler 			fSelected.height = 480;
1113a10cf76eSAxel Dörfler 			fSelected.space = B_CMAP8;
1114a10cf76eSAxel Dörfler 			fSelected.refresh = 60.0;
1115a10cf76eSAxel Dörfler 			fSelected.combine = kCombineDisable;
1116a10cf76eSAxel Dörfler 			fSelected.swap_displays = false;
1117a10cf76eSAxel Dörfler 			fSelected.use_laptop_panel = false;
1118a10cf76eSAxel Dörfler 			fSelected.tv_standard = 0;
1119a10cf76eSAxel Dörfler 
1120b21d610eSAxel Dörfler 			// TODO: workspace defaults
1121abc649b8SWaldemar Kornewald 
11225de171daSAxel Dörfler 			_UpdateControls();
1123a10cf76eSAxel Dörfler 			break;
1124a10cf76eSAxel Dörfler 		}
1125a10cf76eSAxel Dörfler 
112610e9b12fSWaldemar Kornewald 		case BUTTON_UNDO_MSG:
112761c5c89bSAxel Dörfler 			fUndoScreenMode.Revert();
11285de171daSAxel Dörfler 			_UpdateActiveMode();
1129abc649b8SWaldemar Kornewald 			break;
1130abc649b8SWaldemar Kornewald 
1131abc649b8SWaldemar Kornewald 		case BUTTON_REVERT_MSG:
1132abc649b8SWaldemar Kornewald 		{
1133abc649b8SWaldemar Kornewald 			fModified = false;
1134199893c3SAxel Dörfler 			fBootWorkspaceApplied = false;
1135abc649b8SWaldemar Kornewald 
1136b21d610eSAxel Dörfler 			// ScreenMode::Revert() assumes that we first set the correct
1137b21d610eSAxel Dörfler 			// number of workspaces
1138b21d610eSAxel Dörfler 
1139b21d610eSAxel Dörfler 			BPrivate::set_workspaces_layout(fOriginalWorkspacesColumns,
1140b21d610eSAxel Dörfler 				fOriginalWorkspacesRows);
1141b21d610eSAxel Dörfler 			_UpdateWorkspaceButtons();
1142b21d610eSAxel Dörfler 
1143a10cf76eSAxel Dörfler 			fScreenMode.Revert();
11445de171daSAxel Dörfler 			_UpdateActiveMode();
11453a2b67b5SAdrien Destugues 
11463a2b67b5SAdrien Destugues 			BScreen screen(this);
11473a2b67b5SAdrien Destugues 			screen.SetBrightness(fOriginalBrightness);
11483a2b67b5SAdrien Destugues 			fBrightnessSlider->SetValue(fOriginalBrightness * 255);
1149a10cf76eSAxel Dörfler 			break;
1150abc649b8SWaldemar Kornewald 		}
1151a10cf76eSAxel Dörfler 
1152a10cf76eSAxel Dörfler 		case BUTTON_APPLY_MSG:
11535de171daSAxel Dörfler 			_Apply();
1154a10cf76eSAxel Dörfler 			break;
1155a10cf76eSAxel Dörfler 
1156abc649b8SWaldemar Kornewald 		case MAKE_INITIAL_MSG:
1157abc649b8SWaldemar Kornewald 			// user pressed "keep" in confirmation dialog
1158abc649b8SWaldemar Kornewald 			fModified = true;
11595de171daSAxel Dörfler 			_UpdateActiveMode();
1160a10cf76eSAxel Dörfler 			break;
1161a10cf76eSAxel Dörfler 
1162b8a61399SBrian Hill 		case UPDATE_DESKTOP_COLOR_MSG:
1163b8a61399SBrian Hill 			PostMessage(message, fMonitorView);
1164b8a61399SBrian Hill 			break;
1165b8a61399SBrian Hill 
11663a2b67b5SAdrien Destugues 		case SLIDER_BRIGHTNESS_MSG:
11673a2b67b5SAdrien Destugues 		{
11683a2b67b5SAdrien Destugues 			BScreen screen(this);
11693a2b67b5SAdrien Destugues 			screen.SetBrightness(message->FindInt32("be:value") / 255.f);
11703a2b67b5SAdrien Destugues 			_CheckApplyEnabled();
11713a2b67b5SAdrien Destugues 			break;
11723a2b67b5SAdrien Destugues 		}
11733a2b67b5SAdrien Destugues 
1174a10cf76eSAxel Dörfler 		default:
1175a10cf76eSAxel Dörfler 			BWindow::MessageReceived(message);
1176a10cf76eSAxel Dörfler 	}
1177a10cf76eSAxel Dörfler }
1178a10cf76eSAxel Dörfler 
1179a10cf76eSAxel Dörfler 
118012580984SAxel Dörfler status_t
118112580984SAxel Dörfler ScreenWindow::_WriteVesaModeFile(const screen_mode& mode) const
118212580984SAxel Dörfler {
118312580984SAxel Dörfler 	BPath path;
118412580984SAxel Dörfler 	status_t status = find_directory(B_USER_SETTINGS_DIRECTORY, &path, true);
118512580984SAxel Dörfler 	if (status < B_OK)
118612580984SAxel Dörfler 		return status;
118712580984SAxel Dörfler 
118812580984SAxel Dörfler 	path.Append("kernel/drivers");
118912580984SAxel Dörfler 	status = create_directory(path.Path(), 0755);
119012580984SAxel Dörfler 	if (status < B_OK)
119112580984SAxel Dörfler 		return status;
119212580984SAxel Dörfler 
119312580984SAxel Dörfler 	path.Append("vesa");
119412580984SAxel Dörfler 	BFile file;
119512580984SAxel Dörfler 	status = file.SetTo(path.Path(), B_CREATE_FILE | B_WRITE_ONLY | B_ERASE_FILE);
119612580984SAxel Dörfler 	if (status < B_OK)
119712580984SAxel Dörfler 		return status;
119812580984SAxel Dörfler 
119912580984SAxel Dörfler 	char buffer[256];
12005084d0d4SAlex Smith 	snprintf(buffer, sizeof(buffer), "mode %" B_PRId32 " %" B_PRId32 " %"
12015084d0d4SAlex Smith 		B_PRId32 "\n", mode.width, mode.height, mode.BitsPerPixel());
120212580984SAxel Dörfler 
120312580984SAxel Dörfler 	ssize_t bytesWritten = file.Write(buffer, strlen(buffer));
120412580984SAxel Dörfler 	if (bytesWritten < B_OK)
120512580984SAxel Dörfler 		return bytesWritten;
120612580984SAxel Dörfler 
120712580984SAxel Dörfler 	return B_OK;
120812580984SAxel Dörfler }
120912580984SAxel Dörfler 
121012580984SAxel Dörfler 
1211a10cf76eSAxel Dörfler void
12121fc4cb1fSAxel Dörfler ScreenWindow::_BuildSupportedColorSpaces()
12131fc4cb1fSAxel Dörfler {
12141fc4cb1fSAxel Dörfler 	fSupportedColorSpaces = 0;
12151fc4cb1fSAxel Dörfler 
12161fc4cb1fSAxel Dörfler 	for (int32 i = 0; i < kColorSpaceCount; i++) {
12171fc4cb1fSAxel Dörfler 		for (int32 j = 0; j < fScreenMode.CountModes(); j++) {
12181fc4cb1fSAxel Dörfler 			if (fScreenMode.ModeAt(j).space == kColorSpaces[i].space) {
12191fc4cb1fSAxel Dörfler 				fSupportedColorSpaces |= 1 << i;
12201fc4cb1fSAxel Dörfler 				break;
12211fc4cb1fSAxel Dörfler 			}
12221fc4cb1fSAxel Dörfler 		}
12231fc4cb1fSAxel Dörfler 	}
12241fc4cb1fSAxel Dörfler }
12251fc4cb1fSAxel Dörfler 
12261fc4cb1fSAxel Dörfler 
12271fc4cb1fSAxel Dörfler void
12285de171daSAxel Dörfler ScreenWindow::_CheckApplyEnabled()
1229a10cf76eSAxel Dörfler {
123095ef5044SJanus 	bool applyEnabled = true;
123195ef5044SJanus 
123295ef5044SJanus 	if (fSelected == fActive) {
123395ef5044SJanus 		applyEnabled = false;
123495ef5044SJanus 		if (fAllWorkspacesItem->IsMarked()) {
123595ef5044SJanus 			screen_mode screenMode;
123695ef5044SJanus 			const int32 workspaceCount = count_workspaces();
123795ef5044SJanus 			for (int32 i = 0; i < workspaceCount; i++) {
123895ef5044SJanus 				fScreenMode.Get(screenMode, i);
123995ef5044SJanus 				if (screenMode != fSelected) {
124095ef5044SJanus 					applyEnabled = true;
124195ef5044SJanus 					break;
124295ef5044SJanus 				}
124395ef5044SJanus 			}
124495ef5044SJanus 		}
124595ef5044SJanus 	}
124695ef5044SJanus 
124795ef5044SJanus 	fApplyButton->SetEnabled(applyEnabled);
1248b21d610eSAxel Dörfler 
1249b21d610eSAxel Dörfler 	uint32 columns;
1250b21d610eSAxel Dörfler 	uint32 rows;
1251b21d610eSAxel Dörfler 	BPrivate::get_workspaces_layout(&columns, &rows);
1252b21d610eSAxel Dörfler 
12533a2b67b5SAdrien Destugues 	BScreen screen(this);
12543a2b67b5SAdrien Destugues 	float brightness = -1;
12553a2b67b5SAdrien Destugues 	screen.GetBrightness(&brightness);
12563a2b67b5SAdrien Destugues 
1257b21d610eSAxel Dörfler 	fRevertButton->SetEnabled(columns != fOriginalWorkspacesColumns
1258b21d610eSAxel Dörfler 		|| rows != fOriginalWorkspacesRows
12593a2b67b5SAdrien Destugues 		|| brightness != fOriginalBrightness
12605de171daSAxel Dörfler 		|| fSelected != fOriginal);
1261a10cf76eSAxel Dörfler }
1262a10cf76eSAxel Dörfler 
1263a10cf76eSAxel Dörfler 
1264a10cf76eSAxel Dörfler void
12655de171daSAxel Dörfler ScreenWindow::_UpdateOriginal()
1266abc649b8SWaldemar Kornewald {
1267b21d610eSAxel Dörfler 	BPrivate::get_workspaces_layout(&fOriginalWorkspacesColumns,
1268b21d610eSAxel Dörfler 		&fOriginalWorkspacesRows);
1269b21d610eSAxel Dörfler 
1270abc649b8SWaldemar Kornewald 	fScreenMode.Get(fOriginal);
1271abc649b8SWaldemar Kornewald 	fScreenMode.UpdateOriginalModes();
1272abc649b8SWaldemar Kornewald }
1273abc649b8SWaldemar Kornewald 
1274abc649b8SWaldemar Kornewald 
1275abc649b8SWaldemar Kornewald void
127612966d04SAxel Dörfler ScreenWindow::_UpdateMonitor()
127712966d04SAxel Dörfler {
127812966d04SAxel Dörfler 	monitor_info info;
127912966d04SAxel Dörfler 	float diagonalInches;
128012966d04SAxel Dörfler 	status_t status = fScreenMode.GetMonitorInfo(info, &diagonalInches);
128155030977SAxel Dörfler 	if (status == B_OK) {
12821a8af605SAxel Dörfler 		char text[512];
128366ab1666SAxel Dörfler 		snprintf(text, sizeof(text), "%s%s%s %g\"", info.vendor,
128466ab1666SAxel Dörfler 			info.name[0] ? " " : "", info.name, diagonalInches);
128512966d04SAxel Dörfler 
128612966d04SAxel Dörfler 		fMonitorInfo->SetText(text);
128712966d04SAxel Dörfler 
12888bf216d6SAxel Dörfler 		if (fMonitorInfo->IsHidden(fMonitorInfo))
128912966d04SAxel Dörfler 			fMonitorInfo->Show();
129055030977SAxel Dörfler 	} else {
12918bf216d6SAxel Dörfler 		if (!fMonitorInfo->IsHidden(fMonitorInfo))
129255030977SAxel Dörfler 			fMonitorInfo->Hide();
129355030977SAxel Dörfler 	}
1294af8f9c31SAxel Dörfler 
12958b46ee25SAdrien Destugues 	// Add info about the graphics device
12968b46ee25SAdrien Destugues 
12978b46ee25SAdrien Destugues 	accelerant_device_info deviceInfo;
12988b46ee25SAdrien Destugues 
12998b46ee25SAdrien Destugues 	if (fScreenMode.GetDeviceInfo(deviceInfo) == B_OK) {
13008b46ee25SAdrien Destugues 		BString deviceString;
13018b46ee25SAdrien Destugues 
13028b46ee25SAdrien Destugues 		if (deviceInfo.name[0] && deviceInfo.chipset[0]) {
13038b46ee25SAdrien Destugues 			deviceString.SetToFormat("%s (%s)", deviceInfo.name,
13048b46ee25SAdrien Destugues 				deviceInfo.chipset);
13058b46ee25SAdrien Destugues 		} else if (deviceInfo.name[0] || deviceInfo.chipset[0]) {
13068b46ee25SAdrien Destugues 			deviceString
13078b46ee25SAdrien Destugues 				= deviceInfo.name[0] ? deviceInfo.name : deviceInfo.chipset;
13088b46ee25SAdrien Destugues 		}
13098b46ee25SAdrien Destugues 
13108b46ee25SAdrien Destugues 		fDeviceInfo->SetText(deviceString);
13118b46ee25SAdrien Destugues 	}
13128b46ee25SAdrien Destugues 
13138b46ee25SAdrien Destugues 
131455030977SAxel Dörfler 	char text[512];
13151a8af605SAxel Dörfler 	size_t length = 0;
13161a8af605SAxel Dörfler 	text[0] = 0;
13171a8af605SAxel Dörfler 
131855030977SAxel Dörfler 	if (status == B_OK) {
1319af8f9c31SAxel Dörfler 		if (info.min_horizontal_frequency != 0
1320af8f9c31SAxel Dörfler 			&& info.min_vertical_frequency != 0
1321af8f9c31SAxel Dörfler 			&& info.max_pixel_clock != 0) {
13221a8af605SAxel Dörfler 			length = snprintf(text, sizeof(text),
1323c9e8f97aSAdrien Destugues 				B_TRANSLATE("Horizonal frequency:\t%lu - %lu kHz\n"
13249c1a9b92SAdrien Destugues 				"Vertical frequency:\t%lu - %lu Hz\n\n"
1325c9e8f97aSAdrien Destugues 				"Maximum pixel clock:\t%g MHz"),
13261a8af605SAxel Dörfler 				info.min_horizontal_frequency, info.max_horizontal_frequency,
13271a8af605SAxel Dörfler 				info.min_vertical_frequency, info.max_vertical_frequency,
13281a8af605SAxel Dörfler 				info.max_pixel_clock / 1000.0);
1329af8f9c31SAxel Dörfler 		}
13301a8af605SAxel Dörfler 		if (info.serial_number[0] && length < sizeof(text)) {
13311a8af605SAxel Dörfler 			length += snprintf(text + length, sizeof(text) - length,
1332c9e8f97aSAdrien Destugues 				B_TRANSLATE("%sSerial no.: %s"), length ? "\n\n" : "",
13331a8af605SAxel Dörfler 				info.serial_number);
13341a8af605SAxel Dörfler 			if (info.produced.week != 0 && info.produced.year != 0
13351a8af605SAxel Dörfler 				&& length < sizeof(text)) {
13361a8af605SAxel Dörfler 				length += snprintf(text + length, sizeof(text) - length,
13371a8af605SAxel Dörfler 					" (%u/%u)", info.produced.week, info.produced.year);
13381a8af605SAxel Dörfler 			}
13391a8af605SAxel Dörfler 		}
134055030977SAxel Dörfler 	}
134161c5c89bSAxel Dörfler 
13421a8af605SAxel Dörfler 	if (text[0])
13431a8af605SAxel Dörfler 		fMonitorView->SetToolTip(text);
134412966d04SAxel Dörfler }
134512966d04SAxel Dörfler 
134612966d04SAxel Dörfler 
134712966d04SAxel Dörfler void
13481fc4cb1fSAxel Dörfler ScreenWindow::_UpdateColorLabel()
13491fc4cb1fSAxel Dörfler {
13501fc4cb1fSAxel Dörfler 	BString string;
1351551c9f15SSiarzhuk Zharski 	string << fSelected.BitsPerPixel() << " " << B_TRANSLATE("bits/pixel");
13521fc4cb1fSAxel Dörfler 	fColorsMenu->Superitem()->SetLabel(string.String());
13531fc4cb1fSAxel Dörfler }
13541fc4cb1fSAxel Dörfler 
13551fc4cb1fSAxel Dörfler 
13561fc4cb1fSAxel Dörfler void
13575de171daSAxel Dörfler ScreenWindow::_Apply()
1358a10cf76eSAxel Dörfler {
1359abc649b8SWaldemar Kornewald 	// make checkpoint, so we can undo these changes
136061c5c89bSAxel Dörfler 	fUndoScreenMode.UpdateOriginalModes();
136161c5c89bSAxel Dörfler 
136207184a9eSAxel Dörfler 	status_t status = fScreenMode.Set(fSelected);
136307184a9eSAxel Dörfler 	if (status == B_OK) {
1364abc649b8SWaldemar Kornewald 		// use the mode that has eventually been set and
1365abc649b8SWaldemar Kornewald 		// thus we know to be working; it can differ from
1366abc649b8SWaldemar Kornewald 		// the mode selected by user due to hardware limitation
1367abc649b8SWaldemar Kornewald 		display_mode newMode;
1368abc649b8SWaldemar Kornewald 		BScreen screen(this);
1369abc649b8SWaldemar Kornewald 		screen.GetMode(&newMode);
1370abc649b8SWaldemar Kornewald 
1371abc649b8SWaldemar Kornewald 		if (fAllWorkspacesItem->IsMarked()) {
1372abc649b8SWaldemar Kornewald 			int32 originatingWorkspace = current_workspace();
137395ef5044SJanus 			const int32 workspaceCount = count_workspaces();
137495ef5044SJanus 			for (int32 i = 0; i < workspaceCount; i++) {
1375abc649b8SWaldemar Kornewald 				if (i != originatingWorkspace)
1376abc649b8SWaldemar Kornewald 					screen.SetMode(i, &newMode, true);
1377abc649b8SWaldemar Kornewald 			}
1378199893c3SAxel Dörfler 			fBootWorkspaceApplied = true;
1379199893c3SAxel Dörfler 		} else {
1380199893c3SAxel Dörfler 			if (current_workspace() == 0)
1381199893c3SAxel Dörfler 				fBootWorkspaceApplied = true;
1382abc649b8SWaldemar Kornewald 		}
1383abc649b8SWaldemar Kornewald 
1384a10cf76eSAxel Dörfler 		fActive = fSelected;
1385a10cf76eSAxel Dörfler 
1386abc649b8SWaldemar Kornewald 		// TODO: only show alert when this is an unknown mode
138741f43d56SAugustin Cavalier 		BAlert* window = new AlertWindow(this);
138841f43d56SAugustin Cavalier 		window->Go(NULL);
138907184a9eSAxel Dörfler 	} else {
139007184a9eSAxel Dörfler 		char message[256];
139107184a9eSAxel Dörfler 		snprintf(message, sizeof(message),
1392c9e8f97aSAdrien Destugues 			B_TRANSLATE("The screen mode could not be set:\n\t%s\n"),
1393c9e8f97aSAdrien Destugues 			screen_errors(status));
1394551c9f15SSiarzhuk Zharski 		BAlert* alert = new BAlert(B_TRANSLATE("Warning"), message,
1395c9e8f97aSAdrien Destugues 			B_TRANSLATE("OK"), NULL, NULL,
139607184a9eSAxel Dörfler 			B_WIDTH_AS_USUAL, B_WARNING_ALERT);
1397aed35104SHumdinger 		alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE);
139807184a9eSAxel Dörfler 		alert->Go();
1399a10cf76eSAxel Dörfler 	}
140007184a9eSAxel Dörfler }
1401