xref: /haiku/src/preferences/screen/ScreenWindow.cpp (revision 3a2b67b5ae3750e6a2963e575e7ee2b39f91bf6d)
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)
258a3fa81bdSJohn Scipione 			.AddGrid(B_USE_DEFAULT_SPACING, B_USE_SMALL_SPACING)
259e1c88201SJohn Scipione 				// columns
260e1c88201SJohn Scipione 				.Add(fColumnsControl->CreateLabelLayoutItem(), 0, 0)
261a3fa81bdSJohn Scipione 				.Add(fColumnsControl->CreateTextViewLayoutItem(), 1, 0)
262e1c88201SJohn Scipione 				// rows
263e1c88201SJohn Scipione 				.Add(fRowsControl->CreateLabelLayoutItem(), 0, 1)
264a3fa81bdSJohn Scipione 				.Add(fRowsControl->CreateTextViewLayoutItem(), 1, 1)
265b21d610eSAxel Dörfler 				.End()
26625fd5c7bSAlex Wilson 			.End()
26725fd5c7bSAlex Wilson 		.View());
268b21d610eSAxel Dörfler 
269b21d610eSAxel Dörfler 	fBackgroundsButton = new BButton("BackgroundsButton",
270c9e8f97aSAdrien Destugues 		B_TRANSLATE("Set background" B_UTF8_ELLIPSIS),
271b21d610eSAxel Dörfler 		new BMessage(BUTTON_LAUNCH_BACKGROUNDS_MSG));
272b21d610eSAxel Dörfler 	fBackgroundsButton->SetFontSize(be_plain_font->Size() * 0.9);
273b21d610eSAxel Dörfler 	screenBox->AddChild(fBackgroundsButton);
274a10cf76eSAxel Dörfler 
275a10cf76eSAxel Dörfler 	// box on the right with screen resolution, etc.
276a10cf76eSAxel Dörfler 
277b21d610eSAxel Dörfler 	BBox* controlsBox = new BBox("controls box");
278b21d610eSAxel Dörfler 	controlsBox->SetLabel(workspaceMenuField);
2796048f541SJohn Scipione 	BGroupView* outerControlsView = new BGroupView(B_VERTICAL);
2806048f541SJohn Scipione 	outerControlsView->GroupLayout()->SetInsets(B_USE_DEFAULT_SPACING,
2816048f541SJohn Scipione 		B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING);
282b21d610eSAxel Dörfler 	controlsBox->AddChild(outerControlsView);
283a10cf76eSAxel Dörfler 
284551c9f15SSiarzhuk Zharski 	fResolutionMenu = new BPopUpMenu("resolution", true, true);
285a10cf76eSAxel Dörfler 
28666ab1666SAxel Dörfler 	uint16 maxWidth = 0;
28766ab1666SAxel Dörfler 	uint16 maxHeight = 0;
28866ab1666SAxel Dörfler 	uint16 previousWidth = 0;
28966ab1666SAxel Dörfler 	uint16 previousHeight = 0;
290a10cf76eSAxel Dörfler 	for (int32 i = 0; i < fScreenMode.CountModes(); i++) {
291a10cf76eSAxel Dörfler 		screen_mode mode = fScreenMode.ModeAt(i);
292a10cf76eSAxel Dörfler 
293a10cf76eSAxel Dörfler 		if (mode.width == previousWidth && mode.height == previousHeight)
294a10cf76eSAxel Dörfler 			continue;
295a10cf76eSAxel Dörfler 
296a10cf76eSAxel Dörfler 		previousWidth = mode.width;
297a10cf76eSAxel Dörfler 		previousHeight = mode.height;
29866ab1666SAxel Dörfler 		if (maxWidth < mode.width)
29966ab1666SAxel Dörfler 			maxWidth = mode.width;
30066ab1666SAxel Dörfler 		if (maxHeight < mode.height)
30166ab1666SAxel Dörfler 			maxHeight = mode.height;
302a10cf76eSAxel Dörfler 
303a10cf76eSAxel Dörfler 		BMessage* message = new BMessage(POP_RESOLUTION_MSG);
304a10cf76eSAxel Dörfler 		message->AddInt32("width", mode.width);
305a10cf76eSAxel Dörfler 		message->AddInt32("height", mode.height);
306a10cf76eSAxel Dörfler 
307a10cf76eSAxel Dörfler 		BString name;
308a10cf76eSAxel Dörfler 		name << mode.width << " x " << mode.height;
309a10cf76eSAxel Dörfler 
310a10cf76eSAxel Dörfler 		fResolutionMenu->AddItem(new BMenuItem(name.String(), message));
311a10cf76eSAxel Dörfler 	}
312a10cf76eSAxel Dörfler 
31366ab1666SAxel Dörfler 	fMonitorView->SetMaxResolution(maxWidth, maxHeight);
31466ab1666SAxel Dörfler 
315c9e8f97aSAdrien Destugues 	fResolutionField = new BMenuField("ResolutionMenu",
31610dfe897SAxel Dörfler 		B_TRANSLATE("Resolution:"), fResolutionMenu);
3176048f541SJohn Scipione 	fResolutionField->SetAlignment(B_ALIGN_RIGHT);
318a10cf76eSAxel Dörfler 
319551c9f15SSiarzhuk Zharski 	fColorsMenu = new BPopUpMenu("colors", true, false);
320a10cf76eSAxel Dörfler 
321a10cf76eSAxel Dörfler 	for (int32 i = 0; i < kColorSpaceCount; i++) {
3221fc4cb1fSAxel Dörfler 		if ((fSupportedColorSpaces & (1 << i)) == 0)
3231fc4cb1fSAxel Dörfler 			continue;
3241fc4cb1fSAxel Dörfler 
325a10cf76eSAxel Dörfler 		BMessage* message = new BMessage(POP_COLORS_MSG);
326a10cf76eSAxel Dörfler 		message->AddInt32("bits_per_pixel", kColorSpaces[i].bits_per_pixel);
327a10cf76eSAxel Dörfler 		message->AddInt32("space", kColorSpaces[i].space);
328a10cf76eSAxel Dörfler 
3291fc4cb1fSAxel Dörfler 		BMenuItem* item = new BMenuItem(kColorSpaces[i].label, message);
3301fc4cb1fSAxel Dörfler 		if (kColorSpaces[i].space == screen.ColorSpace())
3311fc4cb1fSAxel Dörfler 			fUserSelectedColorSpace = item;
3321fc4cb1fSAxel Dörfler 
3331fc4cb1fSAxel Dörfler 		fColorsMenu->AddItem(item);
334a10cf76eSAxel Dörfler 	}
335a10cf76eSAxel Dörfler 
336c9e8f97aSAdrien Destugues 	fColorsField = new BMenuField("ColorsMenu", B_TRANSLATE("Colors:"),
33710dfe897SAxel Dörfler 		fColorsMenu);
3386048f541SJohn Scipione 	fColorsField->SetAlignment(B_ALIGN_RIGHT);
339a10cf76eSAxel Dörfler 
340551c9f15SSiarzhuk Zharski 	fRefreshMenu = new BPopUpMenu("refresh rate", true, true);
341a10cf76eSAxel Dörfler 
34229e8a73aSAxel Dörfler 	float min, max;
343ec495b30SRene Gollent 	if (fScreenMode.GetRefreshLimits(fActive, min, max) != B_OK) {
344ec495b30SRene Gollent 		// if we couldn't obtain the refresh limits, reset to the default
345ec495b30SRene Gollent 		// range. Constraints from detected monitors will fine-tune this
346ec495b30SRene Gollent 		// later.
347ec495b30SRene Gollent 		min = kRefreshRates[0];
348ec495b30SRene Gollent 		max = kRefreshRates[kRefreshRateCount - 1];
349ec495b30SRene Gollent 	}
350ec495b30SRene Gollent 
351ec495b30SRene Gollent 	if (min == max) {
35229e8a73aSAxel Dörfler 		// This is a special case for drivers that only support a single
35329e8a73aSAxel Dörfler 		// frequency, like the VESA driver
35429e8a73aSAxel Dörfler 		BString name;
3557e44de36SRene Gollent 		refresh_rate_to_string(min, name);
356cf076964SRene Gollent 		BMessage *message = new BMessage(POP_REFRESH_MSG);
357cf076964SRene Gollent 		message->AddFloat("refresh", min);
358cf076964SRene Gollent 		BMenuItem *item = new BMenuItem(name.String(), message);
3590efb8b66SJerome Duval 		fRefreshMenu->AddItem(item);
36029e8a73aSAxel Dörfler 		item->SetEnabled(false);
36129e8a73aSAxel Dörfler 	} else {
36270a2b1b5SAxel Dörfler 		monitor_info info;
36370a2b1b5SAxel Dörfler 		if (fScreenMode.GetMonitorInfo(info) == B_OK) {
36470a2b1b5SAxel Dörfler 			min = max_c(info.min_vertical_frequency, min);
36570a2b1b5SAxel Dörfler 			max = min_c(info.max_vertical_frequency, max);
36670a2b1b5SAxel Dörfler 		}
36770a2b1b5SAxel Dörfler 
368a10cf76eSAxel Dörfler 		for (int32 i = 0; i < kRefreshRateCount; ++i) {
36970a2b1b5SAxel Dörfler 			if (kRefreshRates[i] < min || kRefreshRates[i] > max)
37070a2b1b5SAxel Dörfler 				continue;
37170a2b1b5SAxel Dörfler 
372a10cf76eSAxel Dörfler 			BString name;
373551c9f15SSiarzhuk Zharski 			name << kRefreshRates[i] << " " << B_TRANSLATE("Hz");
374a10cf76eSAxel Dörfler 
3750efb8b66SJerome Duval 			BMessage *message = new BMessage(POP_REFRESH_MSG);
376a10cf76eSAxel Dörfler 			message->AddFloat("refresh", kRefreshRates[i]);
377a10cf76eSAxel Dörfler 
378a10cf76eSAxel Dörfler 			fRefreshMenu->AddItem(new BMenuItem(name.String(), message));
379a10cf76eSAxel Dörfler 		}
380a10cf76eSAxel Dörfler 
381c9e8f97aSAdrien Destugues 		fOtherRefresh = new BMenuItem(B_TRANSLATE("Other" B_UTF8_ELLIPSIS),
3820efb8b66SJerome Duval 			new BMessage(POP_OTHER_REFRESH_MSG));
383a10cf76eSAxel Dörfler 		fRefreshMenu->AddItem(fOtherRefresh);
38429e8a73aSAxel Dörfler 	}
385a10cf76eSAxel Dörfler 
386c9e8f97aSAdrien Destugues 	fRefreshField = new BMenuField("RefreshMenu", B_TRANSLATE("Refresh rate:"),
38710dfe897SAxel Dörfler 		fRefreshMenu);
3886048f541SJohn Scipione 	fRefreshField->SetAlignment(B_ALIGN_RIGHT);
389b21d610eSAxel Dörfler 
39012580984SAxel Dörfler 	if (_IsVesa())
39112580984SAxel Dörfler 		fRefreshField->Hide();
392a10cf76eSAxel Dörfler 
393a10cf76eSAxel Dörfler 	// enlarged area for multi-monitor settings
394a10cf76eSAxel Dörfler 	{
395a10cf76eSAxel Dörfler 		bool dummy;
396a10cf76eSAxel Dörfler 		uint32 dummy32;
397a10cf76eSAxel Dörfler 		bool multiMonSupport;
398a10cf76eSAxel Dörfler 		bool useLaptopPanelSupport;
399a10cf76eSAxel Dörfler 		bool tvStandardSupport;
400a10cf76eSAxel Dörfler 
401a10cf76eSAxel Dörfler 		multiMonSupport = TestMultiMonSupport(&screen) == B_OK;
402a10cf76eSAxel Dörfler 		useLaptopPanelSupport = GetUseLaptopPanel(&screen, &dummy) == B_OK;
403a10cf76eSAxel Dörfler 		tvStandardSupport = GetTVStandard(&screen, &dummy32) == B_OK;
404a10cf76eSAxel Dörfler 
405a10cf76eSAxel Dörfler 		// even if there is no support, we still create all controls
406a10cf76eSAxel Dörfler 		// to make sure we don't access NULL pointers later on
407a10cf76eSAxel Dörfler 
408551c9f15SSiarzhuk Zharski 		fCombineMenu = new BPopUpMenu("CombineDisplays",
409c9e8f97aSAdrien Destugues 			true, true);
410a10cf76eSAxel Dörfler 
411a10cf76eSAxel Dörfler 		for (int32 i = 0; i < kCombineModeCount; i++) {
4120efb8b66SJerome Duval 			BMessage *message = new BMessage(POP_COMBINE_DISPLAYS_MSG);
413a10cf76eSAxel Dörfler 			message->AddInt32("mode", kCombineModes[i].mode);
414a10cf76eSAxel Dörfler 
415d1516993SAxel Dörfler 			fCombineMenu->AddItem(new BMenuItem(kCombineModes[i].name,
416d1516993SAxel Dörfler 				message));
417a10cf76eSAxel Dörfler 		}
418a10cf76eSAxel Dörfler 
419b21d610eSAxel Dörfler 		fCombineField = new BMenuField("CombineMenu",
42010dfe897SAxel Dörfler 			B_TRANSLATE("Combine displays:"), fCombineMenu);
4216048f541SJohn Scipione 		fCombineField->SetAlignment(B_ALIGN_RIGHT);
422a10cf76eSAxel Dörfler 
423a10cf76eSAxel Dörfler 		if (!multiMonSupport)
424df3f5bacSStephan Aßmus 			fCombineField->Hide();
425a10cf76eSAxel Dörfler 
426551c9f15SSiarzhuk Zharski 		fSwapDisplaysMenu = new BPopUpMenu("SwapDisplays",
427c9e8f97aSAdrien Destugues 			true, true);
428a10cf76eSAxel Dörfler 
429a10cf76eSAxel Dörfler 		// !order is important - we rely that boolean value == idx
4300efb8b66SJerome Duval 		BMessage *message = new BMessage(POP_SWAP_DISPLAYS_MSG);
431a10cf76eSAxel Dörfler 		message->AddBool("swap", false);
432c9e8f97aSAdrien Destugues 		fSwapDisplaysMenu->AddItem(new BMenuItem(B_TRANSLATE("no"), message));
433a10cf76eSAxel Dörfler 
434a10cf76eSAxel Dörfler 		message = new BMessage(POP_SWAP_DISPLAYS_MSG);
435a10cf76eSAxel Dörfler 		message->AddBool("swap", true);
436c9e8f97aSAdrien Destugues 		fSwapDisplaysMenu->AddItem(new BMenuItem(B_TRANSLATE("yes"), message));
437a10cf76eSAxel Dörfler 
438c9e8f97aSAdrien Destugues 		fSwapDisplaysField = new BMenuField("SwapMenu",
43910dfe897SAxel Dörfler 			B_TRANSLATE("Swap displays:"), fSwapDisplaysMenu);
4406048f541SJohn Scipione 		fSwapDisplaysField->SetAlignment(B_ALIGN_RIGHT);
441a10cf76eSAxel Dörfler 
442a10cf76eSAxel Dörfler 		if (!multiMonSupport)
443df3f5bacSStephan Aßmus 			fSwapDisplaysField->Hide();
444a10cf76eSAxel Dörfler 
445551c9f15SSiarzhuk Zharski 		fUseLaptopPanelMenu = new BPopUpMenu("UseLaptopPanel",
446c9e8f97aSAdrien Destugues 			true, true);
447a10cf76eSAxel Dörfler 
448a10cf76eSAxel Dörfler 		// !order is important - we rely that boolean value == idx
449a10cf76eSAxel Dörfler 		message = new BMessage(POP_USE_LAPTOP_PANEL_MSG);
450a10cf76eSAxel Dörfler 		message->AddBool("use", false);
451c9e8f97aSAdrien Destugues 		fUseLaptopPanelMenu->AddItem(new BMenuItem(B_TRANSLATE("if needed"),
452c9e8f97aSAdrien Destugues 			message));
453a10cf76eSAxel Dörfler 
454a10cf76eSAxel Dörfler 		message = new BMessage(POP_USE_LAPTOP_PANEL_MSG);
455a10cf76eSAxel Dörfler 		message->AddBool("use", true);
456c9e8f97aSAdrien Destugues 		fUseLaptopPanelMenu->AddItem(new BMenuItem(B_TRANSLATE("always"),
457c9e8f97aSAdrien Destugues 			message));
458a10cf76eSAxel Dörfler 
459b21d610eSAxel Dörfler 		fUseLaptopPanelField = new BMenuField("UseLaptopPanel",
46010dfe897SAxel Dörfler 			B_TRANSLATE("Use laptop panel:"), fUseLaptopPanelMenu);
4616048f541SJohn Scipione 		fUseLaptopPanelField->SetAlignment(B_ALIGN_RIGHT);
462a10cf76eSAxel Dörfler 
463a10cf76eSAxel Dörfler 		if (!useLaptopPanelSupport)
464df3f5bacSStephan Aßmus 			fUseLaptopPanelField->Hide();
465a10cf76eSAxel Dörfler 
466551c9f15SSiarzhuk Zharski 		fTVStandardMenu = new BPopUpMenu("TVStandard", true, true);
467a10cf76eSAxel Dörfler 
468a10cf76eSAxel Dörfler 		// arbitrary limit
469a10cf76eSAxel Dörfler 		uint32 i;
470a10cf76eSAxel Dörfler 		for (i = 0; i < 100; ++i) {
471a10cf76eSAxel Dörfler 			uint32 mode;
472a10cf76eSAxel Dörfler 			if (GetNthSupportedTVStandard(&screen, i, &mode) != B_OK)
473a10cf76eSAxel Dörfler 				break;
474a10cf76eSAxel Dörfler 
475a10cf76eSAxel Dörfler 			BString name = tv_standard_to_string(mode);
476a10cf76eSAxel Dörfler 
477a10cf76eSAxel Dörfler 			message = new BMessage(POP_TV_STANDARD_MSG);
478a10cf76eSAxel Dörfler 			message->AddInt32("tv_standard", mode);
479a10cf76eSAxel Dörfler 
480a10cf76eSAxel Dörfler 			fTVStandardMenu->AddItem(new BMenuItem(name.String(), message));
481a10cf76eSAxel Dörfler 		}
482a10cf76eSAxel Dörfler 
483c9e8f97aSAdrien Destugues 		fTVStandardField = new BMenuField("tv standard",
48410dfe897SAxel Dörfler 			B_TRANSLATE("Video format:"), fTVStandardMenu);
485df3f5bacSStephan Aßmus 		fTVStandardField->SetAlignment(B_ALIGN_RIGHT);
486a10cf76eSAxel Dörfler 
487b21d610eSAxel Dörfler 		if (!tvStandardSupport || i == 0)
488df3f5bacSStephan Aßmus 			fTVStandardField->Hide();
489a10cf76eSAxel Dörfler 	}
490a10cf76eSAxel Dörfler 
49125fd5c7bSAlex Wilson 	BLayoutBuilder::Group<>(outerControlsView)
4926048f541SJohn Scipione 		.AddGrid(B_USE_DEFAULT_SPACING, B_USE_SMALL_SPACING)
4936048f541SJohn Scipione 			.Add(fResolutionField->CreateLabelLayoutItem(), 0, 0)
4946048f541SJohn Scipione 			.Add(fResolutionField->CreateMenuBarLayoutItem(), 1, 0)
4956048f541SJohn Scipione 			.Add(fColorsField->CreateLabelLayoutItem(), 0, 1)
4966048f541SJohn Scipione 			.Add(fColorsField->CreateMenuBarLayoutItem(), 1, 1)
4976048f541SJohn Scipione 			.Add(fRefreshField->CreateLabelLayoutItem(), 0, 2)
4986048f541SJohn Scipione 			.Add(fRefreshField->CreateMenuBarLayoutItem(), 1, 2)
4996048f541SJohn Scipione 			.Add(fCombineField->CreateLabelLayoutItem(), 0, 3)
5006048f541SJohn Scipione 			.Add(fCombineField->CreateMenuBarLayoutItem(), 1, 3)
5016048f541SJohn Scipione 			.Add(fSwapDisplaysField->CreateLabelLayoutItem(), 0, 4)
5026048f541SJohn Scipione 			.Add(fSwapDisplaysField->CreateMenuBarLayoutItem(), 1, 4)
5036048f541SJohn Scipione 			.Add(fUseLaptopPanelField->CreateLabelLayoutItem(), 0, 5)
5046048f541SJohn Scipione 			.Add(fUseLaptopPanelField->CreateMenuBarLayoutItem(), 1, 5)
5056048f541SJohn Scipione 			.Add(fTVStandardField->CreateLabelLayoutItem(), 0, 6)
5066048f541SJohn Scipione 			.Add(fTVStandardField->CreateMenuBarLayoutItem(), 1, 6)
50725fd5c7bSAlex Wilson 		.End();
508df3f5bacSStephan Aßmus 
509*3a2b67b5SAdrien Destugues 	fBrightnessSlider = new BSlider("brightness", "Brightness",
510*3a2b67b5SAdrien Destugues 		NULL, 0, 255, B_HORIZONTAL);
511*3a2b67b5SAdrien Destugues 
512*3a2b67b5SAdrien Destugues 	status_t result = screen.GetBrightness(&fOriginalBrightness);
513*3a2b67b5SAdrien Destugues 	if (result == B_OK) {
514*3a2b67b5SAdrien Destugues 		fBrightnessSlider->SetModificationMessage(
515*3a2b67b5SAdrien Destugues 			new BMessage(SLIDER_BRIGHTNESS_MSG));
516*3a2b67b5SAdrien Destugues 		fBrightnessSlider->SetValue(fOriginalBrightness * 255);
517*3a2b67b5SAdrien Destugues 	} else {
518*3a2b67b5SAdrien Destugues 		// The driver does not support changing the brightness,
519*3a2b67b5SAdrien Destugues 		// so hide the slider
520*3a2b67b5SAdrien Destugues 		fBrightnessSlider->Hide();
521*3a2b67b5SAdrien Destugues 
522*3a2b67b5SAdrien Destugues 		fOriginalBrightness = -1;
523*3a2b67b5SAdrien Destugues 	}
524*3a2b67b5SAdrien Destugues 
525abc649b8SWaldemar Kornewald 	// TODO: we don't support getting the screen's preferred settings
526abc649b8SWaldemar Kornewald 	/* fDefaultsButton = new BButton(buttonRect, "DefaultsButton", "Defaults",
527b21d610eSAxel Dörfler 		new BMessage(BUTTON_DEFAULTS_MSG));*/
528a10cf76eSAxel Dörfler 
529c9e8f97aSAdrien Destugues 	fApplyButton = new BButton("ApplyButton", B_TRANSLATE("Apply"),
530df3f5bacSStephan Aßmus 		new BMessage(BUTTON_APPLY_MSG));
531df3f5bacSStephan Aßmus 	fApplyButton->SetEnabled(false);
53225fd5c7bSAlex Wilson 	BLayoutBuilder::Group<>(outerControlsView)
533b21d610eSAxel Dörfler 		.AddGlue()
53425fd5c7bSAlex Wilson 		.AddGroup(B_HORIZONTAL)
53525fd5c7bSAlex Wilson 			.AddGlue()
53625fd5c7bSAlex Wilson 			.Add(fApplyButton);
537b21d610eSAxel Dörfler 
538c9e8f97aSAdrien Destugues 	fRevertButton = new BButton("RevertButton", B_TRANSLATE("Revert"),
539b21d610eSAxel Dörfler 		new BMessage(BUTTON_REVERT_MSG));
540b21d610eSAxel Dörfler 	fRevertButton->SetEnabled(false);
541b21d610eSAxel Dörfler 
5424666484fSJohn Scipione 	BLayoutBuilder::Group<>(this, B_VERTICAL, B_USE_DEFAULT_SPACING)
5434666484fSJohn Scipione 		.AddGroup(B_HORIZONTAL)
544a2cb1737SAdrien Destugues 			.AddGroup(B_VERTICAL, 0, 1)
54583cc66b3SJohn Scipione 				.AddStrut(floorf(controlsBox->TopBorderOffset()) - 1)
546b21d610eSAxel Dörfler 				.Add(screenBox)
54783cc66b3SJohn Scipione 				.End()
548*3a2b67b5SAdrien Destugues 			.AddGroup(B_VERTICAL, 0, 1)
549a2cb1737SAdrien Destugues 				.Add(controlsBox, 2)
550*3a2b67b5SAdrien Destugues 				.Add(fBrightnessSlider)
551*3a2b67b5SAdrien Destugues 				.End()
552b21d610eSAxel Dörfler 			.End()
5534666484fSJohn Scipione 		.AddGroup(B_HORIZONTAL, B_USE_DEFAULT_SPACING)
554b21d610eSAxel Dörfler 			.Add(fRevertButton)
5554666484fSJohn Scipione 			.AddGlue()
5564666484fSJohn Scipione 			.End()
557d0ac6099SHumdinger 		.SetInsets(B_USE_WINDOW_SPACING);
558b21d610eSAxel Dörfler 
5595de171daSAxel Dörfler 	_UpdateControls();
56012966d04SAxel Dörfler 	_UpdateMonitor();
5618bf216d6SAxel Dörfler 
5628bf216d6SAxel Dörfler 	MoveOnScreen();
563a10cf76eSAxel Dörfler }
564a10cf76eSAxel Dörfler 
565a10cf76eSAxel Dörfler 
566a10cf76eSAxel Dörfler ScreenWindow::~ScreenWindow()
567a10cf76eSAxel Dörfler {
568a10cf76eSAxel Dörfler 	delete fSettings;
569a10cf76eSAxel Dörfler }
570a10cf76eSAxel Dörfler 
571a10cf76eSAxel Dörfler 
572a10cf76eSAxel Dörfler bool
573a10cf76eSAxel Dörfler ScreenWindow::QuitRequested()
574a10cf76eSAxel Dörfler {
575a10cf76eSAxel Dörfler 	fSettings->SetWindowFrame(Frame());
576199893c3SAxel Dörfler 
577199893c3SAxel Dörfler 	// Write mode of workspace 0 (the boot workspace) to the vesa settings file
578199893c3SAxel Dörfler 	screen_mode vesaMode;
579199893c3SAxel Dörfler 	if (fBootWorkspaceApplied && fScreenMode.Get(vesaMode, 0) == B_OK) {
580199893c3SAxel Dörfler 		status_t status = _WriteVesaModeFile(vesaMode);
58112580984SAxel Dörfler 		if (status < B_OK) {
582c9e8f97aSAdrien Destugues 			BString warning = B_TRANSLATE("Could not write VESA mode settings"
583c9e8f97aSAdrien Destugues 				" file:\n\t");
58412580984SAxel Dörfler 			warning << strerror(status);
585aed35104SHumdinger 			BAlert* alert = new BAlert(B_TRANSLATE("Warning"),
586aed35104SHumdinger 				warning.String(), B_TRANSLATE("OK"), NULL,
587aed35104SHumdinger 				NULL, B_WIDTH_AS_USUAL, B_WARNING_ALERT);
588aed35104SHumdinger 			alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE);
589aed35104SHumdinger 			alert->Go();
59012580984SAxel Dörfler 		}
59112580984SAxel Dörfler 	}
59212580984SAxel Dörfler 
593a10cf76eSAxel Dörfler 	be_app->PostMessage(B_QUIT_REQUESTED);
594a10cf76eSAxel Dörfler 
595a10cf76eSAxel Dörfler 	return BWindow::QuitRequested();
596a10cf76eSAxel Dörfler }
597a10cf76eSAxel Dörfler 
598a10cf76eSAxel Dörfler 
5995de171daSAxel Dörfler /*!	Update resolution list according to combine mode
6001fc4cb1fSAxel Dörfler 	(some resolutions may not be combinable due to memory restrictions).
601a10cf76eSAxel Dörfler */
602a10cf76eSAxel Dörfler void
6035de171daSAxel Dörfler ScreenWindow::_CheckResolutionMenu()
604a10cf76eSAxel Dörfler {
605a10cf76eSAxel Dörfler 	for (int32 i = 0; i < fResolutionMenu->CountItems(); i++)
606a10cf76eSAxel Dörfler 		fResolutionMenu->ItemAt(i)->SetEnabled(false);
607a10cf76eSAxel Dörfler 
608a10cf76eSAxel Dörfler 	for (int32 i = 0; i < fScreenMode.CountModes(); i++) {
609a10cf76eSAxel Dörfler 		screen_mode mode = fScreenMode.ModeAt(i);
610a10cf76eSAxel Dörfler 		if (mode.combine != fSelected.combine)
611a10cf76eSAxel Dörfler 			continue;
612a10cf76eSAxel Dörfler 
613a10cf76eSAxel Dörfler 		BString name;
614a10cf76eSAxel Dörfler 		name << mode.width << " x " << mode.height;
615a10cf76eSAxel Dörfler 
616a10cf76eSAxel Dörfler 		BMenuItem *item = fResolutionMenu->FindItem(name.String());
617a10cf76eSAxel Dörfler 		if (item != NULL)
618a10cf76eSAxel Dörfler 			item->SetEnabled(true);
619a10cf76eSAxel Dörfler 	}
620a10cf76eSAxel Dörfler }
621a10cf76eSAxel Dörfler 
622a10cf76eSAxel Dörfler 
6235de171daSAxel Dörfler /*!	Update color and refresh options according to current mode
6245de171daSAxel Dörfler 	(a color space is made active if there is any mode with
6255de171daSAxel Dörfler 	given resolution and this colour space; same applies for
6265de171daSAxel Dörfler 	refresh rate, though "Other…" is always possible)
627a10cf76eSAxel Dörfler */
628a10cf76eSAxel Dörfler void
6295de171daSAxel Dörfler ScreenWindow::_CheckColorMenu()
630a10cf76eSAxel Dörfler {
6311fc4cb1fSAxel Dörfler 	int32 supportsAnything = false;
6321fc4cb1fSAxel Dörfler 	int32 index = 0;
6331fc4cb1fSAxel Dörfler 
634a10cf76eSAxel Dörfler 	for (int32 i = 0; i < kColorSpaceCount; i++) {
6351fc4cb1fSAxel Dörfler 		if ((fSupportedColorSpaces & (1 << i)) == 0)
6361fc4cb1fSAxel Dörfler 			continue;
6371fc4cb1fSAxel Dörfler 
638a10cf76eSAxel Dörfler 		bool supported = false;
639a10cf76eSAxel Dörfler 
640a10cf76eSAxel Dörfler 		for (int32 j = 0; j < fScreenMode.CountModes(); j++) {
641a10cf76eSAxel Dörfler 			screen_mode mode = fScreenMode.ModeAt(j);
642a10cf76eSAxel Dörfler 
643a10cf76eSAxel Dörfler 			if (fSelected.width == mode.width
644a10cf76eSAxel Dörfler 				&& fSelected.height == mode.height
6451fc4cb1fSAxel Dörfler 				&& kColorSpaces[i].space == mode.space
646a10cf76eSAxel Dörfler 				&& fSelected.combine == mode.combine) {
6471fc4cb1fSAxel Dörfler 				supportsAnything = true;
648a10cf76eSAxel Dörfler 				supported = true;
649a10cf76eSAxel Dörfler 				break;
650a10cf76eSAxel Dörfler 			}
651a10cf76eSAxel Dörfler 		}
652a10cf76eSAxel Dörfler 
6531fc4cb1fSAxel Dörfler 		BMenuItem* item = fColorsMenu->ItemAt(index++);
654a10cf76eSAxel Dörfler 		if (item)
655a10cf76eSAxel Dörfler 			item->SetEnabled(supported);
656a10cf76eSAxel Dörfler 	}
6571fc4cb1fSAxel Dörfler 
6581fc4cb1fSAxel Dörfler 	fColorsField->SetEnabled(supportsAnything);
6591fc4cb1fSAxel Dörfler 
6601fc4cb1fSAxel Dörfler 	if (!supportsAnything)
6611fc4cb1fSAxel Dörfler 		return;
6621fc4cb1fSAxel Dörfler 
6631fc4cb1fSAxel Dörfler 	// Make sure a valid item is selected
6641fc4cb1fSAxel Dörfler 
6651fc4cb1fSAxel Dörfler 	BMenuItem* item = fColorsMenu->FindMarked();
6661fc4cb1fSAxel Dörfler 	bool changed = false;
6671fc4cb1fSAxel Dörfler 
6681fc4cb1fSAxel Dörfler 	if (item != fUserSelectedColorSpace) {
6691fc4cb1fSAxel Dörfler 		if (fUserSelectedColorSpace != NULL
6701fc4cb1fSAxel Dörfler 			&& fUserSelectedColorSpace->IsEnabled()) {
6711fc4cb1fSAxel Dörfler 			fUserSelectedColorSpace->SetMarked(true);
6721fc4cb1fSAxel Dörfler 			item = fUserSelectedColorSpace;
6731fc4cb1fSAxel Dörfler 			changed = true;
6741fc4cb1fSAxel Dörfler 		}
6751fc4cb1fSAxel Dörfler 	}
6761fc4cb1fSAxel Dörfler 	if (item != NULL && !item->IsEnabled()) {
6771fc4cb1fSAxel Dörfler 		// find the next best item
6781fc4cb1fSAxel Dörfler 		int32 index = fColorsMenu->IndexOf(item);
6791fc4cb1fSAxel Dörfler 		bool found = false;
6801fc4cb1fSAxel Dörfler 
6811fc4cb1fSAxel Dörfler 		for (int32 i = index + 1; i < fColorsMenu->CountItems(); i++) {
6821fc4cb1fSAxel Dörfler 			item = fColorsMenu->ItemAt(i);
6831fc4cb1fSAxel Dörfler 			if (item->IsEnabled()) {
6841fc4cb1fSAxel Dörfler 				found = true;
6851fc4cb1fSAxel Dörfler 				break;
6861fc4cb1fSAxel Dörfler 			}
6871fc4cb1fSAxel Dörfler 		}
6881fc4cb1fSAxel Dörfler 		if (!found) {
6891fc4cb1fSAxel Dörfler 			// search backwards as well
6901fc4cb1fSAxel Dörfler 			for (int32 i = index - 1; i >= 0; i--) {
6911fc4cb1fSAxel Dörfler 				item = fColorsMenu->ItemAt(i);
6921fc4cb1fSAxel Dörfler 				if (item->IsEnabled())
6931fc4cb1fSAxel Dörfler 					break;
6941fc4cb1fSAxel Dörfler 			}
6951fc4cb1fSAxel Dörfler 		}
6961fc4cb1fSAxel Dörfler 
6971fc4cb1fSAxel Dörfler 		item->SetMarked(true);
6981fc4cb1fSAxel Dörfler 		changed = true;
6991fc4cb1fSAxel Dörfler 	}
7001fc4cb1fSAxel Dörfler 
7011fc4cb1fSAxel Dörfler 	if (changed) {
7021fc4cb1fSAxel Dörfler 		// Update selected space
7031fc4cb1fSAxel Dörfler 
7041fc4cb1fSAxel Dörfler 		BMessage* message = item->Message();
7051fc4cb1fSAxel Dörfler 		int32 space;
7061fc4cb1fSAxel Dörfler 		if (message->FindInt32("space", &space) == B_OK) {
7071fc4cb1fSAxel Dörfler 			fSelected.space = (color_space)space;
7081fc4cb1fSAxel Dörfler 			_UpdateColorLabel();
7091fc4cb1fSAxel Dörfler 		}
7101fc4cb1fSAxel Dörfler 	}
711a10cf76eSAxel Dörfler }
712a10cf76eSAxel Dörfler 
713a10cf76eSAxel Dörfler 
7145de171daSAxel Dörfler /*!	Enable/disable refresh options according to current mode. */
715a10cf76eSAxel Dörfler void
7165de171daSAxel Dörfler ScreenWindow::_CheckRefreshMenu()
717a10cf76eSAxel Dörfler {
71829e8a73aSAxel Dörfler 	float min, max;
71929e8a73aSAxel Dörfler 	if (fScreenMode.GetRefreshLimits(fSelected, min, max) != B_OK || min == max)
72029e8a73aSAxel Dörfler 		return;
721a10cf76eSAxel Dörfler 
72229e8a73aSAxel Dörfler 	for (int32 i = fRefreshMenu->CountItems(); i-- > 0;) {
72329e8a73aSAxel Dörfler 		BMenuItem* item = fRefreshMenu->ItemAt(i);
72429e8a73aSAxel Dörfler 		BMessage* message = item->Message();
72529e8a73aSAxel Dörfler 		float refresh;
72629e8a73aSAxel Dörfler 		if (message != NULL && message->FindFloat("refresh", &refresh) == B_OK)
72729e8a73aSAxel Dörfler 			item->SetEnabled(refresh >= min && refresh <= max);
728a10cf76eSAxel Dörfler 	}
729a10cf76eSAxel Dörfler }
730a10cf76eSAxel Dörfler 
731a10cf76eSAxel Dörfler 
7325de171daSAxel Dörfler /*!	Activate appropriate menu item according to selected refresh rate */
733a10cf76eSAxel Dörfler void
7345de171daSAxel Dörfler ScreenWindow::_UpdateRefreshControl()
735a10cf76eSAxel Dörfler {
7367e44de36SRene Gollent 	for (int32 i = 0; i < fRefreshMenu->CountItems(); i++) {
7377e44de36SRene Gollent 		BMenuItem* item = fRefreshMenu->ItemAt(i);
7387e44de36SRene Gollent 		if (item->Message()->FindFloat("refresh") == fSelected.refresh) {
739a10cf76eSAxel Dörfler 			item->SetMarked(true);
74026747978SAdrien Destugues 			// "Other" items only contains a refresh rate when active
74126747978SAdrien Destugues 			fOtherRefresh->SetLabel(B_TRANSLATE("Other" B_UTF8_ELLIPSIS));
742a10cf76eSAxel Dörfler 			return;
743a10cf76eSAxel Dörfler 		}
7447e44de36SRene Gollent 	}
745a10cf76eSAxel Dörfler 
746a10cf76eSAxel Dörfler 	// this is a non-standard refresh rate
7477e44de36SRene Gollent 	if (fOtherRefresh != NULL) {
748a10cf76eSAxel Dörfler 		fOtherRefresh->Message()->ReplaceFloat("refresh", fSelected.refresh);
749a10cf76eSAxel Dörfler 		fOtherRefresh->SetMarked(true);
750a10cf76eSAxel Dörfler 
7517e44de36SRene Gollent 		BString string;
7527e44de36SRene Gollent 		refresh_rate_to_string(fSelected.refresh, string);
753a10cf76eSAxel Dörfler 		fRefreshMenu->Superitem()->SetLabel(string.String());
754a10cf76eSAxel Dörfler 
755c9e8f97aSAdrien Destugues 		string.Append(B_TRANSLATE("/other" B_UTF8_ELLIPSIS));
756a10cf76eSAxel Dörfler 		fOtherRefresh->SetLabel(string.String());
757a10cf76eSAxel Dörfler 	}
7587e44de36SRene Gollent }
759a10cf76eSAxel Dörfler 
760a10cf76eSAxel Dörfler 
761a10cf76eSAxel Dörfler void
7625de171daSAxel Dörfler ScreenWindow::_UpdateMonitorView()
763a10cf76eSAxel Dörfler {
764a10cf76eSAxel Dörfler 	BMessage updateMessage(UPDATE_DESKTOP_MSG);
765a10cf76eSAxel Dörfler 	updateMessage.AddInt32("width", fSelected.width);
766a10cf76eSAxel Dörfler 	updateMessage.AddInt32("height", fSelected.height);
767a10cf76eSAxel Dörfler 
768a10cf76eSAxel Dörfler 	PostMessage(&updateMessage, fMonitorView);
769a10cf76eSAxel Dörfler }
770a10cf76eSAxel Dörfler 
771a10cf76eSAxel Dörfler 
772a10cf76eSAxel Dörfler void
7735de171daSAxel Dörfler ScreenWindow::_UpdateControls()
774a10cf76eSAxel Dörfler {
775b21d610eSAxel Dörfler 	_UpdateWorkspaceButtons();
776b21d610eSAxel Dörfler 
777a10cf76eSAxel Dörfler 	BMenuItem* item = fSwapDisplaysMenu->ItemAt((int32)fSelected.swap_displays);
778c33a865cSJohn Scipione 	if (item != NULL && !item->IsMarked())
779a10cf76eSAxel Dörfler 		item->SetMarked(true);
780a10cf76eSAxel Dörfler 
781a10cf76eSAxel Dörfler 	item = fUseLaptopPanelMenu->ItemAt((int32)fSelected.use_laptop_panel);
782c33a865cSJohn Scipione 	if (item != NULL && !item->IsMarked())
783a10cf76eSAxel Dörfler 		item->SetMarked(true);
784a10cf76eSAxel Dörfler 
785a10cf76eSAxel Dörfler 	for (int32 i = 0; i < fTVStandardMenu->CountItems(); i++) {
786a10cf76eSAxel Dörfler 		item = fTVStandardMenu->ItemAt(i);
787a10cf76eSAxel Dörfler 
788a10cf76eSAxel Dörfler 		uint32 tvStandard;
789a10cf76eSAxel Dörfler 		item->Message()->FindInt32("tv_standard", (int32 *)&tvStandard);
790a10cf76eSAxel Dörfler 		if (tvStandard == fSelected.tv_standard) {
791a10cf76eSAxel Dörfler 			if (!item->IsMarked())
792a10cf76eSAxel Dörfler 				item->SetMarked(true);
793a10cf76eSAxel Dörfler 			break;
794a10cf76eSAxel Dörfler 		}
795a10cf76eSAxel Dörfler 	}
796a10cf76eSAxel Dörfler 
7975de171daSAxel Dörfler 	_CheckResolutionMenu();
7985de171daSAxel Dörfler 	_CheckColorMenu();
7995de171daSAxel Dörfler 	_CheckRefreshMenu();
800a10cf76eSAxel Dörfler 
801a10cf76eSAxel Dörfler 	BString string;
802a10cf76eSAxel Dörfler 	resolution_to_string(fSelected, string);
803a10cf76eSAxel Dörfler 	item = fResolutionMenu->FindItem(string.String());
804a10cf76eSAxel Dörfler 
805a10cf76eSAxel Dörfler 	if (item != NULL) {
806a10cf76eSAxel Dörfler 		if (!item->IsMarked())
807a10cf76eSAxel Dörfler 			item->SetMarked(true);
808a10cf76eSAxel Dörfler 	} else {
809a10cf76eSAxel Dörfler 		// this is bad luck - if mode has been set via screen references,
810a10cf76eSAxel Dörfler 		// this case cannot occur; there are three possible solutions:
811a10cf76eSAxel Dörfler 		// 1. add a new resolution to list
812a10cf76eSAxel Dörfler 		//    - we had to remove it as soon as a "valid" one is selected
813a10cf76eSAxel Dörfler 		//    - we don't know which frequencies/bit depths are supported
814a10cf76eSAxel Dörfler 		//    - as long as we haven't the GMT formula to create
815a10cf76eSAxel Dörfler 		//      parameters for any resolution given, we cannot
816a10cf76eSAxel Dörfler 		//      really set current mode - it's just not in the list
817a10cf76eSAxel Dörfler 		// 2. choose nearest resolution
818a10cf76eSAxel Dörfler 		//    - probably a good idea, but implies coding and testing
819a10cf76eSAxel Dörfler 		// 3. choose lowest resolution
820a10cf76eSAxel Dörfler 		//    - do you really think we are so lazy? yes, we are
821a10cf76eSAxel Dörfler 		item = fResolutionMenu->ItemAt(0);
822a10cf76eSAxel Dörfler 		if (item)
823a10cf76eSAxel Dörfler 			item->SetMarked(true);
824a10cf76eSAxel Dörfler 
825a10cf76eSAxel Dörfler 		// okay - at least we set menu label to active resolution
826a10cf76eSAxel Dörfler 		fResolutionMenu->Superitem()->SetLabel(string.String());
827a10cf76eSAxel Dörfler 	}
828a10cf76eSAxel Dörfler 
829a10cf76eSAxel Dörfler 	// mark active combine mode
830a10cf76eSAxel Dörfler 	for (int32 i = 0; i < kCombineModeCount; i++) {
831a10cf76eSAxel Dörfler 		if (kCombineModes[i].mode == fSelected.combine) {
832a10cf76eSAxel Dörfler 			item = fCombineMenu->ItemAt(i);
833c33a865cSJohn Scipione 			if (item != NULL && !item->IsMarked())
834a10cf76eSAxel Dörfler 				item->SetMarked(true);
835a10cf76eSAxel Dörfler 			break;
836a10cf76eSAxel Dörfler 		}
837a10cf76eSAxel Dörfler 	}
838a10cf76eSAxel Dörfler 
839a10cf76eSAxel Dörfler 	item = fColorsMenu->ItemAt(0);
840a10cf76eSAxel Dörfler 
8411fc4cb1fSAxel Dörfler 	for (int32 i = 0, index = 0; i <  kColorSpaceCount; i++) {
8421fc4cb1fSAxel Dörfler 		if ((fSupportedColorSpaces & (1 << i)) == 0)
8431fc4cb1fSAxel Dörfler 			continue;
8441fc4cb1fSAxel Dörfler 
8451fc4cb1fSAxel Dörfler 		if (kColorSpaces[i].space == fSelected.space) {
8461fc4cb1fSAxel Dörfler 			item = fColorsMenu->ItemAt(index);
847a10cf76eSAxel Dörfler 			break;
848a10cf76eSAxel Dörfler 		}
8491fc4cb1fSAxel Dörfler 
8501fc4cb1fSAxel Dörfler 		index++;
851a10cf76eSAxel Dörfler 	}
852a10cf76eSAxel Dörfler 
853c33a865cSJohn Scipione 	if (item != NULL && !item->IsMarked())
854a10cf76eSAxel Dörfler 		item->SetMarked(true);
855a10cf76eSAxel Dörfler 
8561fc4cb1fSAxel Dörfler 	_UpdateColorLabel();
8575de171daSAxel Dörfler 	_UpdateMonitorView();
8585de171daSAxel Dörfler 	_UpdateRefreshControl();
859a10cf76eSAxel Dörfler 
8605de171daSAxel Dörfler 	_CheckApplyEnabled();
861a10cf76eSAxel Dörfler }
862a10cf76eSAxel Dörfler 
863a10cf76eSAxel Dörfler 
86412580984SAxel Dörfler /*! Reflect active mode in chosen settings */
865a10cf76eSAxel Dörfler void
8665de171daSAxel Dörfler ScreenWindow::_UpdateActiveMode()
867a10cf76eSAxel Dörfler {
868c491b5adSJohn Scipione 	_UpdateActiveMode(current_workspace());
869c491b5adSJohn Scipione }
870c491b5adSJohn Scipione 
871c491b5adSJohn Scipione 
872c491b5adSJohn Scipione void
873c491b5adSJohn Scipione ScreenWindow::_UpdateActiveMode(int32 workspace)
874c491b5adSJohn Scipione {
87512580984SAxel Dörfler 	// Usually, this function gets called after a mode
876a10cf76eSAxel Dörfler 	// has been set manually; still, as the graphics driver
877a10cf76eSAxel Dörfler 	// is free to fiddle with mode passed, we better ask
878a10cf76eSAxel Dörfler 	// what kind of mode we actually got
879c491b5adSJohn Scipione 	if (fScreenMode.Get(fActive, workspace) == B_OK) {
880a10cf76eSAxel Dörfler 		fSelected = fActive;
881a10cf76eSAxel Dörfler 
88212966d04SAxel Dörfler 		_UpdateMonitor();
883c491b5adSJohn Scipione 		_BuildSupportedColorSpaces();
8845de171daSAxel Dörfler 		_UpdateControls();
885a10cf76eSAxel Dörfler 	}
886c491b5adSJohn Scipione }
887a10cf76eSAxel Dörfler 
888a10cf76eSAxel Dörfler 
889a10cf76eSAxel Dörfler void
890b21d610eSAxel Dörfler ScreenWindow::_UpdateWorkspaceButtons()
891b21d610eSAxel Dörfler {
892b21d610eSAxel Dörfler 	uint32 columns;
893b21d610eSAxel Dörfler 	uint32 rows;
894b21d610eSAxel Dörfler 	BPrivate::get_workspaces_layout(&columns, &rows);
895b21d610eSAxel Dörfler 
896a3fa81bdSJohn Scipione 	// Set the max values enabling/disabling the up/down arrows
897b21d610eSAxel Dörfler 
898a3fa81bdSJohn Scipione 	if (rows == 1)
899a3fa81bdSJohn Scipione 		fColumnsControl->SetMaxValue(32);
900a3fa81bdSJohn Scipione 	else if (rows == 2)
901a3fa81bdSJohn Scipione 		fColumnsControl->SetMaxValue(16);
902a3fa81bdSJohn Scipione 	else if (rows <= 4)
903a3fa81bdSJohn Scipione 		fColumnsControl->SetMaxValue(8);
904a3fa81bdSJohn Scipione 	else if (rows <= 8)
905a3fa81bdSJohn Scipione 		fColumnsControl->SetMaxValue(4);
906a3fa81bdSJohn Scipione 	else if (rows <= 16)
907a3fa81bdSJohn Scipione 		fColumnsControl->SetMaxValue(2);
908a3fa81bdSJohn Scipione 	else if (rows <= 32)
909a3fa81bdSJohn Scipione 		fColumnsControl->SetMaxValue(1);
910b21d610eSAxel Dörfler 
911a3fa81bdSJohn Scipione 	if (columns == 1)
912a3fa81bdSJohn Scipione 		fRowsControl->SetMaxValue(32);
913a3fa81bdSJohn Scipione 	else if (columns == 2)
914a3fa81bdSJohn Scipione 		fRowsControl->SetMaxValue(16);
915a3fa81bdSJohn Scipione 	else if (columns <= 4)
916a3fa81bdSJohn Scipione 		fRowsControl->SetMaxValue(8);
917a3fa81bdSJohn Scipione 	else if (columns <= 8)
918a3fa81bdSJohn Scipione 		fRowsControl->SetMaxValue(4);
919a3fa81bdSJohn Scipione 	else if (columns <= 16)
920a3fa81bdSJohn Scipione 		fRowsControl->SetMaxValue(2);
921a3fa81bdSJohn Scipione 	else if (columns <= 32)
922a3fa81bdSJohn Scipione 		fRowsControl->SetMaxValue(1);
923b21d610eSAxel Dörfler }
924b21d610eSAxel Dörfler 
925b21d610eSAxel Dörfler 
926b21d610eSAxel Dörfler void
927a10cf76eSAxel Dörfler ScreenWindow::ScreenChanged(BRect frame, color_space mode)
928a10cf76eSAxel Dörfler {
929a10cf76eSAxel Dörfler 	// move window on screen, if necessary
930a10cf76eSAxel Dörfler 	if (frame.right <= Frame().right
931a10cf76eSAxel Dörfler 		&& frame.bottom <= Frame().bottom) {
932a10cf76eSAxel Dörfler 		MoveTo((frame.Width() - Frame().Width()) / 2,
933a10cf76eSAxel Dörfler 			(frame.Height() - Frame().Height()) / 2);
934a10cf76eSAxel Dörfler 	}
935a10cf76eSAxel Dörfler }
936a10cf76eSAxel Dörfler 
937a10cf76eSAxel Dörfler 
938a10cf76eSAxel Dörfler void
939a10cf76eSAxel Dörfler ScreenWindow::WorkspaceActivated(int32 workspace, bool state)
940a10cf76eSAxel Dörfler {
941c491b5adSJohn Scipione 	if (fScreenMode.GetOriginalMode(fOriginal, workspace) == B_OK) {
942c491b5adSJohn Scipione 		_UpdateActiveMode(workspace);
943a10cf76eSAxel Dörfler 
9446edaa0f6SStefano Ceccherini 		BMessage message(UPDATE_DESKTOP_COLOR_MSG);
9456edaa0f6SStefano Ceccherini 		PostMessage(&message, fMonitorView);
946a10cf76eSAxel Dörfler 	}
947c491b5adSJohn Scipione }
948a10cf76eSAxel Dörfler 
949a10cf76eSAxel Dörfler 
950a10cf76eSAxel Dörfler void
951a10cf76eSAxel Dörfler ScreenWindow::MessageReceived(BMessage* message)
952a10cf76eSAxel Dörfler {
953a10cf76eSAxel Dörfler 	switch (message->what) {
954a10cf76eSAxel Dörfler 		case WORKSPACE_CHECK_MSG:
9555de171daSAxel Dörfler 			_CheckApplyEnabled();
956a10cf76eSAxel Dörfler 			break;
957a10cf76eSAxel Dörfler 
958b21d610eSAxel Dörfler 		case kMsgWorkspaceColumnsChanged:
959b21d610eSAxel Dörfler 		{
960a3fa81bdSJohn Scipione 			uint32 newColumns = (uint32)fColumnsControl->Value();
961b21d610eSAxel Dörfler 
962b21d610eSAxel Dörfler 			uint32 rows;
963b21d610eSAxel Dörfler 			BPrivate::get_workspaces_layout(NULL, &rows);
964b21d610eSAxel Dörfler 			BPrivate::set_workspaces_layout(newColumns, rows);
965b21d610eSAxel Dörfler 
966b21d610eSAxel Dörfler 			_UpdateWorkspaceButtons();
967a3fa81bdSJohn Scipione 			fRowsControl->SetValue(rows);
968a3fa81bdSJohn Scipione 				// enables/disables up/down arrows
969b21d610eSAxel Dörfler 			_CheckApplyEnabled();
970a3fa81bdSJohn Scipione 
971b21d610eSAxel Dörfler 			break;
972b21d610eSAxel Dörfler 		}
973b21d610eSAxel Dörfler 
974b21d610eSAxel Dörfler 		case kMsgWorkspaceRowsChanged:
975b21d610eSAxel Dörfler 		{
976a3fa81bdSJohn Scipione 			uint32 newRows = (uint32)fRowsControl->Value();
977b21d610eSAxel Dörfler 
978b21d610eSAxel Dörfler 			uint32 columns;
979b21d610eSAxel Dörfler 			BPrivate::get_workspaces_layout(&columns, NULL);
980b21d610eSAxel Dörfler 			BPrivate::set_workspaces_layout(columns, newRows);
981b21d610eSAxel Dörfler 
982b21d610eSAxel Dörfler 			_UpdateWorkspaceButtons();
983a3fa81bdSJohn Scipione 			fColumnsControl->SetValue(columns);
984a3fa81bdSJohn Scipione 				// enables/disables up/down arrows
985b21d610eSAxel Dörfler 			_CheckApplyEnabled();
986a10cf76eSAxel Dörfler 			break;
987a10cf76eSAxel Dörfler 		}
988a10cf76eSAxel Dörfler 
989a10cf76eSAxel Dörfler 		case POP_RESOLUTION_MSG:
990a10cf76eSAxel Dörfler 		{
991a10cf76eSAxel Dörfler 			message->FindInt32("width", &fSelected.width);
992a10cf76eSAxel Dörfler 			message->FindInt32("height", &fSelected.height);
993a10cf76eSAxel Dörfler 
9945de171daSAxel Dörfler 			_CheckColorMenu();
9955de171daSAxel Dörfler 			_CheckRefreshMenu();
996a10cf76eSAxel Dörfler 
9975de171daSAxel Dörfler 			_UpdateMonitorView();
9985de171daSAxel Dörfler 			_UpdateRefreshControl();
999a10cf76eSAxel Dörfler 
10005de171daSAxel Dörfler 			_CheckApplyEnabled();
1001a10cf76eSAxel Dörfler 			break;
1002a10cf76eSAxel Dörfler 		}
1003a10cf76eSAxel Dörfler 
1004a10cf76eSAxel Dörfler 		case POP_COLORS_MSG:
1005a10cf76eSAxel Dörfler 		{
10061fc4cb1fSAxel Dörfler 			int32 space;
10071fc4cb1fSAxel Dörfler 			if (message->FindInt32("space", &space) != B_OK)
10081fc4cb1fSAxel Dörfler 				break;
1009a10cf76eSAxel Dörfler 
10101fc4cb1fSAxel Dörfler 			int32 index;
10111fc4cb1fSAxel Dörfler 			if (message->FindInt32("index", &index) == B_OK
10121fc4cb1fSAxel Dörfler 				&& fColorsMenu->ItemAt(index) != NULL)
10131fc4cb1fSAxel Dörfler 				fUserSelectedColorSpace = fColorsMenu->ItemAt(index);
10141fc4cb1fSAxel Dörfler 
10151fc4cb1fSAxel Dörfler 			fSelected.space = (color_space)space;
10161fc4cb1fSAxel Dörfler 			_UpdateColorLabel();
1017a10cf76eSAxel Dörfler 
10185de171daSAxel Dörfler 			_CheckApplyEnabled();
1019a10cf76eSAxel Dörfler 			break;
1020a10cf76eSAxel Dörfler 		}
1021a10cf76eSAxel Dörfler 
1022a10cf76eSAxel Dörfler 		case POP_REFRESH_MSG:
1023a40498e2SWaldemar Kornewald 		{
1024a10cf76eSAxel Dörfler 			message->FindFloat("refresh", &fSelected.refresh);
1025c9e8f97aSAdrien Destugues 			fOtherRefresh->SetLabel(B_TRANSLATE("Other" B_UTF8_ELLIPSIS));
10261fc4cb1fSAxel Dörfler 				// revert "Other…" label - it might have a refresh rate prefix
1027a10cf76eSAxel Dörfler 
10285de171daSAxel Dörfler 			_CheckApplyEnabled();
1029a10cf76eSAxel Dörfler 			break;
1030a40498e2SWaldemar Kornewald 		}
1031a10cf76eSAxel Dörfler 
1032a10cf76eSAxel Dörfler 		case POP_OTHER_REFRESH_MSG:
1033a10cf76eSAxel Dörfler 		{
103429e8a73aSAxel Dörfler 			// make sure menu shows something useful
10355de171daSAxel Dörfler 			_UpdateRefreshControl();
1036a10cf76eSAxel Dörfler 
103729e8a73aSAxel Dörfler 			float min = 0, max = 999;
103829e8a73aSAxel Dörfler 			fScreenMode.GetRefreshLimits(fSelected, min, max);
103929e8a73aSAxel Dörfler 			if (min < gMinRefresh)
104029e8a73aSAxel Dörfler 				min = gMinRefresh;
104129e8a73aSAxel Dörfler 			if (max > gMaxRefresh)
104229e8a73aSAxel Dörfler 				max = gMaxRefresh;
104329e8a73aSAxel Dörfler 
104470a2b1b5SAxel Dörfler 			monitor_info info;
104570a2b1b5SAxel Dörfler 			if (fScreenMode.GetMonitorInfo(info) == B_OK) {
104670a2b1b5SAxel Dörfler 				min = max_c(info.min_vertical_frequency, min);
104770a2b1b5SAxel Dörfler 				max = min_c(info.max_vertical_frequency, max);
104870a2b1b5SAxel Dörfler 			}
104970a2b1b5SAxel Dörfler 
1050c5d10f7aSAxel Dörfler 			RefreshWindow *fRefreshWindow = new RefreshWindow(
105170a2b1b5SAxel Dörfler 				fRefreshField->ConvertToScreen(B_ORIGIN), fSelected.refresh,
105270a2b1b5SAxel Dörfler 				min, max);
1053a10cf76eSAxel Dörfler 			fRefreshWindow->Show();
1054a10cf76eSAxel Dörfler 			break;
1055a10cf76eSAxel Dörfler 		}
1056a10cf76eSAxel Dörfler 
1057a10cf76eSAxel Dörfler 		case SET_CUSTOM_REFRESH_MSG:
1058a10cf76eSAxel Dörfler 		{
1059a10cf76eSAxel Dörfler 			// user pressed "done" in "Other…" refresh dialog;
1060a10cf76eSAxel Dörfler 			// select the refresh rate chosen
1061a10cf76eSAxel Dörfler 			message->FindFloat("refresh", &fSelected.refresh);
1062a10cf76eSAxel Dörfler 
10635de171daSAxel Dörfler 			_UpdateRefreshControl();
10645de171daSAxel Dörfler 			_CheckApplyEnabled();
1065a10cf76eSAxel Dörfler 			break;
1066a10cf76eSAxel Dörfler 		}
1067a10cf76eSAxel Dörfler 
1068a10cf76eSAxel Dörfler 		case POP_COMBINE_DISPLAYS_MSG:
1069a10cf76eSAxel Dörfler 		{
1070a10cf76eSAxel Dörfler 			// new combine mode has bee chosen
1071a10cf76eSAxel Dörfler 			int32 mode;
1072a10cf76eSAxel Dörfler 			if (message->FindInt32("mode", &mode) == B_OK)
1073a10cf76eSAxel Dörfler 				fSelected.combine = (combine_mode)mode;
1074a10cf76eSAxel Dörfler 
10755de171daSAxel Dörfler 			_CheckResolutionMenu();
10765de171daSAxel Dörfler 			_CheckApplyEnabled();
1077a10cf76eSAxel Dörfler 			break;
1078a10cf76eSAxel Dörfler 		}
1079a10cf76eSAxel Dörfler 
1080a10cf76eSAxel Dörfler 		case POP_SWAP_DISPLAYS_MSG:
1081a10cf76eSAxel Dörfler 			message->FindBool("swap", &fSelected.swap_displays);
10825de171daSAxel Dörfler 			_CheckApplyEnabled();
1083a10cf76eSAxel Dörfler 			break;
1084a10cf76eSAxel Dörfler 
1085a10cf76eSAxel Dörfler 		case POP_USE_LAPTOP_PANEL_MSG:
1086a10cf76eSAxel Dörfler 			message->FindBool("use", &fSelected.use_laptop_panel);
10875de171daSAxel Dörfler 			_CheckApplyEnabled();
1088a10cf76eSAxel Dörfler 			break;
1089a10cf76eSAxel Dörfler 
1090a10cf76eSAxel Dörfler 		case POP_TV_STANDARD_MSG:
1091a10cf76eSAxel Dörfler 			message->FindInt32("tv_standard", (int32 *)&fSelected.tv_standard);
10925de171daSAxel Dörfler 			_CheckApplyEnabled();
1093a10cf76eSAxel Dörfler 			break;
1094a10cf76eSAxel Dörfler 
1095df3f5bacSStephan Aßmus 		case BUTTON_LAUNCH_BACKGROUNDS_MSG:
10966f095d6aSRyan Leavengood 			if (be_roster->Launch(kBackgroundsSignature) == B_ALREADY_RUNNING) {
10976f095d6aSRyan Leavengood 				app_info info;
10986f095d6aSRyan Leavengood 				be_roster->GetAppInfo(kBackgroundsSignature, &info);
10996f095d6aSRyan Leavengood 				be_roster->ActivateApp(info.team);
11006f095d6aSRyan Leavengood 			}
1101df3f5bacSStephan Aßmus 			break;
1102df3f5bacSStephan Aßmus 
1103a10cf76eSAxel Dörfler 		case BUTTON_DEFAULTS_MSG:
1104a10cf76eSAxel Dörfler 		{
11054be51fe3SWaldemar Kornewald 			// TODO: get preferred settings of screen
1106a10cf76eSAxel Dörfler 			fSelected.width = 640;
1107a10cf76eSAxel Dörfler 			fSelected.height = 480;
1108a10cf76eSAxel Dörfler 			fSelected.space = B_CMAP8;
1109a10cf76eSAxel Dörfler 			fSelected.refresh = 60.0;
1110a10cf76eSAxel Dörfler 			fSelected.combine = kCombineDisable;
1111a10cf76eSAxel Dörfler 			fSelected.swap_displays = false;
1112a10cf76eSAxel Dörfler 			fSelected.use_laptop_panel = false;
1113a10cf76eSAxel Dörfler 			fSelected.tv_standard = 0;
1114a10cf76eSAxel Dörfler 
1115b21d610eSAxel Dörfler 			// TODO: workspace defaults
1116abc649b8SWaldemar Kornewald 
11175de171daSAxel Dörfler 			_UpdateControls();
1118a10cf76eSAxel Dörfler 			break;
1119a10cf76eSAxel Dörfler 		}
1120a10cf76eSAxel Dörfler 
112110e9b12fSWaldemar Kornewald 		case BUTTON_UNDO_MSG:
112261c5c89bSAxel Dörfler 			fUndoScreenMode.Revert();
11235de171daSAxel Dörfler 			_UpdateActiveMode();
1124abc649b8SWaldemar Kornewald 			break;
1125abc649b8SWaldemar Kornewald 
1126abc649b8SWaldemar Kornewald 		case BUTTON_REVERT_MSG:
1127abc649b8SWaldemar Kornewald 		{
1128abc649b8SWaldemar Kornewald 			fModified = false;
1129199893c3SAxel Dörfler 			fBootWorkspaceApplied = false;
1130abc649b8SWaldemar Kornewald 
1131b21d610eSAxel Dörfler 			// ScreenMode::Revert() assumes that we first set the correct
1132b21d610eSAxel Dörfler 			// number of workspaces
1133b21d610eSAxel Dörfler 
1134b21d610eSAxel Dörfler 			BPrivate::set_workspaces_layout(fOriginalWorkspacesColumns,
1135b21d610eSAxel Dörfler 				fOriginalWorkspacesRows);
1136b21d610eSAxel Dörfler 			_UpdateWorkspaceButtons();
1137b21d610eSAxel Dörfler 
1138a10cf76eSAxel Dörfler 			fScreenMode.Revert();
11395de171daSAxel Dörfler 			_UpdateActiveMode();
1140*3a2b67b5SAdrien Destugues 
1141*3a2b67b5SAdrien Destugues 			BScreen screen(this);
1142*3a2b67b5SAdrien Destugues 			screen.SetBrightness(fOriginalBrightness);
1143*3a2b67b5SAdrien Destugues 			fBrightnessSlider->SetValue(fOriginalBrightness * 255);
1144a10cf76eSAxel Dörfler 			break;
1145abc649b8SWaldemar Kornewald 		}
1146a10cf76eSAxel Dörfler 
1147a10cf76eSAxel Dörfler 		case BUTTON_APPLY_MSG:
11485de171daSAxel Dörfler 			_Apply();
1149a10cf76eSAxel Dörfler 			break;
1150a10cf76eSAxel Dörfler 
1151abc649b8SWaldemar Kornewald 		case MAKE_INITIAL_MSG:
1152abc649b8SWaldemar Kornewald 			// user pressed "keep" in confirmation dialog
1153abc649b8SWaldemar Kornewald 			fModified = true;
11545de171daSAxel Dörfler 			_UpdateActiveMode();
1155a10cf76eSAxel Dörfler 			break;
1156a10cf76eSAxel Dörfler 
1157b8a61399SBrian Hill 		case UPDATE_DESKTOP_COLOR_MSG:
1158b8a61399SBrian Hill 			PostMessage(message, fMonitorView);
1159b8a61399SBrian Hill 			break;
1160b8a61399SBrian Hill 
1161*3a2b67b5SAdrien Destugues 		case SLIDER_BRIGHTNESS_MSG:
1162*3a2b67b5SAdrien Destugues 		{
1163*3a2b67b5SAdrien Destugues 			BScreen screen(this);
1164*3a2b67b5SAdrien Destugues 			screen.SetBrightness(message->FindInt32("be:value") / 255.f);
1165*3a2b67b5SAdrien Destugues 			_CheckApplyEnabled();
1166*3a2b67b5SAdrien Destugues 			break;
1167*3a2b67b5SAdrien Destugues 		}
1168*3a2b67b5SAdrien Destugues 
1169a10cf76eSAxel Dörfler 		default:
1170a10cf76eSAxel Dörfler 			BWindow::MessageReceived(message);
1171a10cf76eSAxel Dörfler 	}
1172a10cf76eSAxel Dörfler }
1173a10cf76eSAxel Dörfler 
1174a10cf76eSAxel Dörfler 
117512580984SAxel Dörfler status_t
117612580984SAxel Dörfler ScreenWindow::_WriteVesaModeFile(const screen_mode& mode) const
117712580984SAxel Dörfler {
117812580984SAxel Dörfler 	BPath path;
117912580984SAxel Dörfler 	status_t status = find_directory(B_USER_SETTINGS_DIRECTORY, &path, true);
118012580984SAxel Dörfler 	if (status < B_OK)
118112580984SAxel Dörfler 		return status;
118212580984SAxel Dörfler 
118312580984SAxel Dörfler 	path.Append("kernel/drivers");
118412580984SAxel Dörfler 	status = create_directory(path.Path(), 0755);
118512580984SAxel Dörfler 	if (status < B_OK)
118612580984SAxel Dörfler 		return status;
118712580984SAxel Dörfler 
118812580984SAxel Dörfler 	path.Append("vesa");
118912580984SAxel Dörfler 	BFile file;
119012580984SAxel Dörfler 	status = file.SetTo(path.Path(), B_CREATE_FILE | B_WRITE_ONLY | B_ERASE_FILE);
119112580984SAxel Dörfler 	if (status < B_OK)
119212580984SAxel Dörfler 		return status;
119312580984SAxel Dörfler 
119412580984SAxel Dörfler 	char buffer[256];
11955084d0d4SAlex Smith 	snprintf(buffer, sizeof(buffer), "mode %" B_PRId32 " %" B_PRId32 " %"
11965084d0d4SAlex Smith 		B_PRId32 "\n", mode.width, mode.height, mode.BitsPerPixel());
119712580984SAxel Dörfler 
119812580984SAxel Dörfler 	ssize_t bytesWritten = file.Write(buffer, strlen(buffer));
119912580984SAxel Dörfler 	if (bytesWritten < B_OK)
120012580984SAxel Dörfler 		return bytesWritten;
120112580984SAxel Dörfler 
120212580984SAxel Dörfler 	return B_OK;
120312580984SAxel Dörfler }
120412580984SAxel Dörfler 
120512580984SAxel Dörfler 
1206a10cf76eSAxel Dörfler void
12071fc4cb1fSAxel Dörfler ScreenWindow::_BuildSupportedColorSpaces()
12081fc4cb1fSAxel Dörfler {
12091fc4cb1fSAxel Dörfler 	fSupportedColorSpaces = 0;
12101fc4cb1fSAxel Dörfler 
12111fc4cb1fSAxel Dörfler 	for (int32 i = 0; i < kColorSpaceCount; i++) {
12121fc4cb1fSAxel Dörfler 		for (int32 j = 0; j < fScreenMode.CountModes(); j++) {
12131fc4cb1fSAxel Dörfler 			if (fScreenMode.ModeAt(j).space == kColorSpaces[i].space) {
12141fc4cb1fSAxel Dörfler 				fSupportedColorSpaces |= 1 << i;
12151fc4cb1fSAxel Dörfler 				break;
12161fc4cb1fSAxel Dörfler 			}
12171fc4cb1fSAxel Dörfler 		}
12181fc4cb1fSAxel Dörfler 	}
12191fc4cb1fSAxel Dörfler }
12201fc4cb1fSAxel Dörfler 
12211fc4cb1fSAxel Dörfler 
12221fc4cb1fSAxel Dörfler void
12235de171daSAxel Dörfler ScreenWindow::_CheckApplyEnabled()
1224a10cf76eSAxel Dörfler {
122595ef5044SJanus 	bool applyEnabled = true;
122695ef5044SJanus 
122795ef5044SJanus 	if (fSelected == fActive) {
122895ef5044SJanus 		applyEnabled = false;
122995ef5044SJanus 		if (fAllWorkspacesItem->IsMarked()) {
123095ef5044SJanus 			screen_mode screenMode;
123195ef5044SJanus 			const int32 workspaceCount = count_workspaces();
123295ef5044SJanus 			for (int32 i = 0; i < workspaceCount; i++) {
123395ef5044SJanus 				fScreenMode.Get(screenMode, i);
123495ef5044SJanus 				if (screenMode != fSelected) {
123595ef5044SJanus 					applyEnabled = true;
123695ef5044SJanus 					break;
123795ef5044SJanus 				}
123895ef5044SJanus 			}
123995ef5044SJanus 		}
124095ef5044SJanus 	}
124195ef5044SJanus 
124295ef5044SJanus 	fApplyButton->SetEnabled(applyEnabled);
1243b21d610eSAxel Dörfler 
1244b21d610eSAxel Dörfler 	uint32 columns;
1245b21d610eSAxel Dörfler 	uint32 rows;
1246b21d610eSAxel Dörfler 	BPrivate::get_workspaces_layout(&columns, &rows);
1247b21d610eSAxel Dörfler 
1248*3a2b67b5SAdrien Destugues 	BScreen screen(this);
1249*3a2b67b5SAdrien Destugues 	float brightness = -1;
1250*3a2b67b5SAdrien Destugues 	screen.GetBrightness(&brightness);
1251*3a2b67b5SAdrien Destugues 
1252b21d610eSAxel Dörfler 	fRevertButton->SetEnabled(columns != fOriginalWorkspacesColumns
1253b21d610eSAxel Dörfler 		|| rows != fOriginalWorkspacesRows
1254*3a2b67b5SAdrien Destugues 		|| brightness != fOriginalBrightness
12555de171daSAxel Dörfler 		|| fSelected != fOriginal);
1256a10cf76eSAxel Dörfler }
1257a10cf76eSAxel Dörfler 
1258a10cf76eSAxel Dörfler 
1259a10cf76eSAxel Dörfler void
12605de171daSAxel Dörfler ScreenWindow::_UpdateOriginal()
1261abc649b8SWaldemar Kornewald {
1262b21d610eSAxel Dörfler 	BPrivate::get_workspaces_layout(&fOriginalWorkspacesColumns,
1263b21d610eSAxel Dörfler 		&fOriginalWorkspacesRows);
1264b21d610eSAxel Dörfler 
1265abc649b8SWaldemar Kornewald 	fScreenMode.Get(fOriginal);
1266abc649b8SWaldemar Kornewald 	fScreenMode.UpdateOriginalModes();
1267abc649b8SWaldemar Kornewald }
1268abc649b8SWaldemar Kornewald 
1269abc649b8SWaldemar Kornewald 
1270abc649b8SWaldemar Kornewald void
127112966d04SAxel Dörfler ScreenWindow::_UpdateMonitor()
127212966d04SAxel Dörfler {
127312966d04SAxel Dörfler 	monitor_info info;
127412966d04SAxel Dörfler 	float diagonalInches;
127512966d04SAxel Dörfler 	status_t status = fScreenMode.GetMonitorInfo(info, &diagonalInches);
127655030977SAxel Dörfler 	if (status == B_OK) {
12771a8af605SAxel Dörfler 		char text[512];
127866ab1666SAxel Dörfler 		snprintf(text, sizeof(text), "%s%s%s %g\"", info.vendor,
127966ab1666SAxel Dörfler 			info.name[0] ? " " : "", info.name, diagonalInches);
128012966d04SAxel Dörfler 
128112966d04SAxel Dörfler 		fMonitorInfo->SetText(text);
128212966d04SAxel Dörfler 
12838bf216d6SAxel Dörfler 		if (fMonitorInfo->IsHidden(fMonitorInfo))
128412966d04SAxel Dörfler 			fMonitorInfo->Show();
128555030977SAxel Dörfler 	} else {
12868bf216d6SAxel Dörfler 		if (!fMonitorInfo->IsHidden(fMonitorInfo))
128755030977SAxel Dörfler 			fMonitorInfo->Hide();
128855030977SAxel Dörfler 	}
1289af8f9c31SAxel Dörfler 
12908b46ee25SAdrien Destugues 	// Add info about the graphics device
12918b46ee25SAdrien Destugues 
12928b46ee25SAdrien Destugues 	accelerant_device_info deviceInfo;
12938b46ee25SAdrien Destugues 
12948b46ee25SAdrien Destugues 	if (fScreenMode.GetDeviceInfo(deviceInfo) == B_OK) {
12958b46ee25SAdrien Destugues 		BString deviceString;
12968b46ee25SAdrien Destugues 
12978b46ee25SAdrien Destugues 		if (deviceInfo.name[0] && deviceInfo.chipset[0]) {
12988b46ee25SAdrien Destugues 			deviceString.SetToFormat("%s (%s)", deviceInfo.name,
12998b46ee25SAdrien Destugues 				deviceInfo.chipset);
13008b46ee25SAdrien Destugues 		} else if (deviceInfo.name[0] || deviceInfo.chipset[0]) {
13018b46ee25SAdrien Destugues 			deviceString
13028b46ee25SAdrien Destugues 				= deviceInfo.name[0] ? deviceInfo.name : deviceInfo.chipset;
13038b46ee25SAdrien Destugues 		}
13048b46ee25SAdrien Destugues 
13058b46ee25SAdrien Destugues 		fDeviceInfo->SetText(deviceString);
13068b46ee25SAdrien Destugues 	}
13078b46ee25SAdrien Destugues 
13088b46ee25SAdrien Destugues 
130955030977SAxel Dörfler 	char text[512];
13101a8af605SAxel Dörfler 	size_t length = 0;
13111a8af605SAxel Dörfler 	text[0] = 0;
13121a8af605SAxel Dörfler 
131355030977SAxel Dörfler 	if (status == B_OK) {
1314af8f9c31SAxel Dörfler 		if (info.min_horizontal_frequency != 0
1315af8f9c31SAxel Dörfler 			&& info.min_vertical_frequency != 0
1316af8f9c31SAxel Dörfler 			&& info.max_pixel_clock != 0) {
13171a8af605SAxel Dörfler 			length = snprintf(text, sizeof(text),
1318c9e8f97aSAdrien Destugues 				B_TRANSLATE("Horizonal frequency:\t%lu - %lu kHz\n"
13199c1a9b92SAdrien Destugues 				"Vertical frequency:\t%lu - %lu Hz\n\n"
1320c9e8f97aSAdrien Destugues 				"Maximum pixel clock:\t%g MHz"),
13211a8af605SAxel Dörfler 				info.min_horizontal_frequency, info.max_horizontal_frequency,
13221a8af605SAxel Dörfler 				info.min_vertical_frequency, info.max_vertical_frequency,
13231a8af605SAxel Dörfler 				info.max_pixel_clock / 1000.0);
1324af8f9c31SAxel Dörfler 		}
13251a8af605SAxel Dörfler 		if (info.serial_number[0] && length < sizeof(text)) {
13261a8af605SAxel Dörfler 			length += snprintf(text + length, sizeof(text) - length,
1327c9e8f97aSAdrien Destugues 				B_TRANSLATE("%sSerial no.: %s"), length ? "\n\n" : "",
13281a8af605SAxel Dörfler 				info.serial_number);
13291a8af605SAxel Dörfler 			if (info.produced.week != 0 && info.produced.year != 0
13301a8af605SAxel Dörfler 				&& length < sizeof(text)) {
13311a8af605SAxel Dörfler 				length += snprintf(text + length, sizeof(text) - length,
13321a8af605SAxel Dörfler 					" (%u/%u)", info.produced.week, info.produced.year);
13331a8af605SAxel Dörfler 			}
13341a8af605SAxel Dörfler 		}
133555030977SAxel Dörfler 	}
133661c5c89bSAxel Dörfler 
13371a8af605SAxel Dörfler 	if (text[0])
13381a8af605SAxel Dörfler 		fMonitorView->SetToolTip(text);
133912966d04SAxel Dörfler }
134012966d04SAxel Dörfler 
134112966d04SAxel Dörfler 
134212966d04SAxel Dörfler void
13431fc4cb1fSAxel Dörfler ScreenWindow::_UpdateColorLabel()
13441fc4cb1fSAxel Dörfler {
13451fc4cb1fSAxel Dörfler 	BString string;
1346551c9f15SSiarzhuk Zharski 	string << fSelected.BitsPerPixel() << " " << B_TRANSLATE("bits/pixel");
13471fc4cb1fSAxel Dörfler 	fColorsMenu->Superitem()->SetLabel(string.String());
13481fc4cb1fSAxel Dörfler }
13491fc4cb1fSAxel Dörfler 
13501fc4cb1fSAxel Dörfler 
13511fc4cb1fSAxel Dörfler void
13525de171daSAxel Dörfler ScreenWindow::_Apply()
1353a10cf76eSAxel Dörfler {
1354abc649b8SWaldemar Kornewald 	// make checkpoint, so we can undo these changes
135561c5c89bSAxel Dörfler 	fUndoScreenMode.UpdateOriginalModes();
135661c5c89bSAxel Dörfler 
135707184a9eSAxel Dörfler 	status_t status = fScreenMode.Set(fSelected);
135807184a9eSAxel Dörfler 	if (status == B_OK) {
1359abc649b8SWaldemar Kornewald 		// use the mode that has eventually been set and
1360abc649b8SWaldemar Kornewald 		// thus we know to be working; it can differ from
1361abc649b8SWaldemar Kornewald 		// the mode selected by user due to hardware limitation
1362abc649b8SWaldemar Kornewald 		display_mode newMode;
1363abc649b8SWaldemar Kornewald 		BScreen screen(this);
1364abc649b8SWaldemar Kornewald 		screen.GetMode(&newMode);
1365abc649b8SWaldemar Kornewald 
1366abc649b8SWaldemar Kornewald 		if (fAllWorkspacesItem->IsMarked()) {
1367abc649b8SWaldemar Kornewald 			int32 originatingWorkspace = current_workspace();
136895ef5044SJanus 			const int32 workspaceCount = count_workspaces();
136995ef5044SJanus 			for (int32 i = 0; i < workspaceCount; i++) {
1370abc649b8SWaldemar Kornewald 				if (i != originatingWorkspace)
1371abc649b8SWaldemar Kornewald 					screen.SetMode(i, &newMode, true);
1372abc649b8SWaldemar Kornewald 			}
1373199893c3SAxel Dörfler 			fBootWorkspaceApplied = true;
1374199893c3SAxel Dörfler 		} else {
1375199893c3SAxel Dörfler 			if (current_workspace() == 0)
1376199893c3SAxel Dörfler 				fBootWorkspaceApplied = true;
1377abc649b8SWaldemar Kornewald 		}
1378abc649b8SWaldemar Kornewald 
1379a10cf76eSAxel Dörfler 		fActive = fSelected;
1380a10cf76eSAxel Dörfler 
1381abc649b8SWaldemar Kornewald 		// TODO: only show alert when this is an unknown mode
138241f43d56SAugustin Cavalier 		BAlert* window = new AlertWindow(this);
138341f43d56SAugustin Cavalier 		window->Go(NULL);
138407184a9eSAxel Dörfler 	} else {
138507184a9eSAxel Dörfler 		char message[256];
138607184a9eSAxel Dörfler 		snprintf(message, sizeof(message),
1387c9e8f97aSAdrien Destugues 			B_TRANSLATE("The screen mode could not be set:\n\t%s\n"),
1388c9e8f97aSAdrien Destugues 			screen_errors(status));
1389551c9f15SSiarzhuk Zharski 		BAlert* alert = new BAlert(B_TRANSLATE("Warning"), message,
1390c9e8f97aSAdrien Destugues 			B_TRANSLATE("OK"), NULL, NULL,
139107184a9eSAxel Dörfler 			B_WIDTH_AS_USUAL, B_WARNING_ALERT);
1392aed35104SHumdinger 		alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE);
139307184a9eSAxel Dörfler 		alert->Go();
1394a10cf76eSAxel Dörfler 	}
139507184a9eSAxel Dörfler }
1396