1a10cf76eSAxel Dörfler /* 2b21d610eSAxel Dörfler * Copyright 2001-2009, Haiku. 3a10cf76eSAxel Dörfler * Distributed under the terms of the MIT License. 4a10cf76eSAxel Dörfler * 5a10cf76eSAxel Dörfler * Authors: 6a10cf76eSAxel Dörfler * Rafael Romo 7a10cf76eSAxel Dörfler * Stefano Ceccherini (burton666@libero.it) 8a10cf76eSAxel Dörfler * Andrew Bachmann 9a10cf76eSAxel Dörfler * Thomas Kurschel 10a10cf76eSAxel Dörfler * Axel Dörfler, axeld@pinc-software.de 11df3f5bacSStephan Aßmus * Stephan Aßmus <superstippi@gmx.de> 12b72c4836SAlexandre Deckner * Alexandre Deckner, alex@zappotek.com 13a10cf76eSAxel Dörfler */ 14a10cf76eSAxel Dörfler 15a10cf76eSAxel Dörfler 16b21d610eSAxel Dörfler #include "ScreenWindow.h" 17b21d610eSAxel Dörfler 18b21d610eSAxel Dörfler #include <stdio.h> 19b21d610eSAxel Dörfler #include <stdlib.h> 20b21d610eSAxel Dörfler #include <string.h> 21b21d610eSAxel Dörfler 22b21d610eSAxel Dörfler #include <Alert.h> 23b21d610eSAxel Dörfler #include <Application.h> 24b21d610eSAxel Dörfler #include <Box.h> 25b21d610eSAxel Dörfler #include <Button.h> 26b21d610eSAxel Dörfler #include <Directory.h> 27b21d610eSAxel Dörfler #include <File.h> 28b21d610eSAxel Dörfler #include <FindDirectory.h> 29b21d610eSAxel Dörfler #include <InterfaceDefs.h> 30b21d610eSAxel Dörfler #include <LayoutBuilder.h> 31b21d610eSAxel Dörfler #include <MenuBar.h> 32b21d610eSAxel Dörfler #include <MenuItem.h> 33b21d610eSAxel Dörfler #include <MenuField.h> 34b21d610eSAxel Dörfler #include <Messenger.h> 35b21d610eSAxel Dörfler #include <Path.h> 36b21d610eSAxel Dörfler #include <PopUpMenu.h> 37b21d610eSAxel Dörfler #include <Screen.h> 38b21d610eSAxel Dörfler #include <String.h> 39b21d610eSAxel Dörfler #include <StringView.h> 40b21d610eSAxel Dörfler #include <Roster.h> 41b21d610eSAxel Dörfler #include <Window.h> 42b21d610eSAxel Dörfler 43b21d610eSAxel Dörfler #include <InterfacePrivate.h> 44b21d610eSAxel Dörfler 45a10cf76eSAxel Dörfler #include "AlertWindow.h" 46a10cf76eSAxel Dörfler #include "Constants.h" 47a10cf76eSAxel Dörfler #include "RefreshWindow.h" 48a10cf76eSAxel Dörfler #include "MonitorView.h" 49a10cf76eSAxel Dörfler #include "ScreenSettings.h" 50a10cf76eSAxel Dörfler #include "Utility.h" 51a10cf76eSAxel Dörfler 52a10cf76eSAxel Dörfler /* Note, this headers defines a *private* interface to the Radeon accelerant. 53a10cf76eSAxel Dörfler * It's a solution that works with the current BeOS interface that Haiku 54a10cf76eSAxel Dörfler * adopted. 55a10cf76eSAxel Dörfler * However, it's not a nice and clean solution. Don't use this header in any 56a10cf76eSAxel Dörfler * application if you can avoid it. No other driver is using this, or should 57a10cf76eSAxel Dörfler * be using this. 58a10cf76eSAxel Dörfler * It will be replaced as soon as we introduce an updated accelerant interface 59a10cf76eSAxel Dörfler * which may even happen before R1 hits the streets. 60a10cf76eSAxel Dörfler */ 61a10cf76eSAxel Dörfler #include "multimon.h" // the usual: DANGER WILL, ROBINSON! 62a10cf76eSAxel Dörfler 63a10cf76eSAxel Dörfler 64c5d80d47SAxel Dörfler const char* kBackgroundsSignature = "application/x-vnd.haiku-backgrounds"; 65c5d80d47SAxel Dörfler 66a10cf76eSAxel Dörfler // list of officially supported colour spaces 67a10cf76eSAxel Dörfler static const struct { 68a10cf76eSAxel Dörfler color_space space; 69a10cf76eSAxel Dörfler int32 bits_per_pixel; 70a10cf76eSAxel Dörfler const char* label; 71a10cf76eSAxel Dörfler } kColorSpaces[] = { 72a10cf76eSAxel Dörfler { B_CMAP8, 8, "8 Bits/Pixel, 256 Colors" }, 73a10cf76eSAxel Dörfler { B_RGB15, 15, "15 Bits/Pixel, 32768 Colors" }, 74a10cf76eSAxel Dörfler { B_RGB16, 16, "16 Bits/Pixel, 65536 Colors" }, 75a10cf76eSAxel Dörfler { B_RGB32, 32, "32 Bits/Pixel, 16 Million Colors" } 76a10cf76eSAxel Dörfler }; 77b21d610eSAxel Dörfler static const int32 kColorSpaceCount 78b21d610eSAxel Dörfler = sizeof(kColorSpaces) / sizeof(kColorSpaces[0]); 79a10cf76eSAxel Dörfler 80a10cf76eSAxel Dörfler // list of standard refresh rates 81a796facfSAxel Dörfler static const int32 kRefreshRates[] = { 60, 70, 72, 75, 80, 85, 95, 100 }; 82b21d610eSAxel Dörfler static const int32 kRefreshRateCount 83b21d610eSAxel Dörfler = sizeof(kRefreshRates) / sizeof(kRefreshRates[0]); 84a10cf76eSAxel Dörfler 85a10cf76eSAxel Dörfler // list of combine modes 86a10cf76eSAxel Dörfler static const struct { 87a10cf76eSAxel Dörfler combine_mode mode; 88a10cf76eSAxel Dörfler const char *name; 89a10cf76eSAxel Dörfler } kCombineModes[] = { 90a10cf76eSAxel Dörfler { kCombineDisable, "disable" }, 91a10cf76eSAxel Dörfler { kCombineHorizontally, "horizontally" }, 92a10cf76eSAxel Dörfler { kCombineVertically, "vertically" } 93a10cf76eSAxel Dörfler }; 94b21d610eSAxel Dörfler static const int32 kCombineModeCount 95b21d610eSAxel Dörfler = sizeof(kCombineModes) / sizeof(kCombineModes[0]); 9629e8a73aSAxel Dörfler 97a10cf76eSAxel Dörfler 98a10cf76eSAxel Dörfler static BString 99a10cf76eSAxel Dörfler tv_standard_to_string(uint32 mode) 100a10cf76eSAxel Dörfler { 101a10cf76eSAxel Dörfler switch (mode) { 102a10cf76eSAxel Dörfler case 0: return "disabled"; 103a10cf76eSAxel Dörfler case 1: return "NTSC"; 104a10cf76eSAxel Dörfler case 2: return "NTSC Japan"; 105a10cf76eSAxel Dörfler case 3: return "PAL BDGHI"; 106a10cf76eSAxel Dörfler case 4: return "PAL M"; 107a10cf76eSAxel Dörfler case 5: return "PAL N"; 108a10cf76eSAxel Dörfler case 6: return "SECAM"; 109a10cf76eSAxel Dörfler case 101: return "NTSC 443"; 110a10cf76eSAxel Dörfler case 102: return "PAL 60"; 111a10cf76eSAxel Dörfler case 103: return "PAL NC"; 112a10cf76eSAxel Dörfler default: 113a10cf76eSAxel Dörfler { 114a10cf76eSAxel Dörfler BString name; 115a10cf76eSAxel Dörfler name << "??? (" << mode << ")"; 116a10cf76eSAxel Dörfler 117a10cf76eSAxel Dörfler return name; 118a10cf76eSAxel Dörfler } 119a10cf76eSAxel Dörfler } 120a10cf76eSAxel Dörfler } 121a10cf76eSAxel Dörfler 122a10cf76eSAxel Dörfler 123a10cf76eSAxel Dörfler static void 124a10cf76eSAxel Dörfler resolution_to_string(screen_mode& mode, BString &string) 125a10cf76eSAxel Dörfler { 126a10cf76eSAxel Dörfler string << mode.width << " x " << mode.height; 127a10cf76eSAxel Dörfler } 128a10cf76eSAxel Dörfler 129a10cf76eSAxel Dörfler 130a10cf76eSAxel Dörfler static void 131a10cf76eSAxel Dörfler refresh_rate_to_string(float refresh, BString &string, 132a10cf76eSAxel Dörfler bool appendUnit = true, bool alwaysWithFraction = false) 133a10cf76eSAxel Dörfler { 134a10cf76eSAxel Dörfler snprintf(string.LockBuffer(32), 32, "%.*g", refresh >= 100.0 ? 4 : 3, refresh); 135a10cf76eSAxel Dörfler string.UnlockBuffer(); 136a10cf76eSAxel Dörfler 137a10cf76eSAxel Dörfler if (appendUnit) 138a10cf76eSAxel Dörfler string << " Hz"; 139a10cf76eSAxel Dörfler } 140a10cf76eSAxel Dörfler 141a10cf76eSAxel Dörfler 14207184a9eSAxel Dörfler static const char* 14307184a9eSAxel Dörfler screen_errors(status_t status) 14407184a9eSAxel Dörfler { 14507184a9eSAxel Dörfler switch (status) { 14607184a9eSAxel Dörfler case B_ENTRY_NOT_FOUND: 14707184a9eSAxel Dörfler return "Unknown Mode"; 14807184a9eSAxel Dörfler // TODO: add more? 14907184a9eSAxel Dörfler 15007184a9eSAxel Dörfler default: 15107184a9eSAxel Dörfler return strerror(status); 15207184a9eSAxel Dörfler } 15307184a9eSAxel Dörfler } 15407184a9eSAxel Dörfler 15529e8a73aSAxel Dörfler 1563dfd20c0SStephan Aßmus // #pragma mark - 1573dfd20c0SStephan Aßmus 1583dfd20c0SStephan Aßmus 1595a78744bSAxel Dörfler ScreenWindow::ScreenWindow(ScreenSettings* settings) 160b21d610eSAxel Dörfler : 161b21d610eSAxel Dörfler BWindow(settings->WindowFrame(), "Screen", B_TITLED_WINDOW, 162b21d610eSAxel Dörfler B_NOT_ZOOMABLE | B_AUTO_UPDATE_SIZE_LIMITS, 163b21d610eSAxel Dörfler B_ALL_WORKSPACES), 164199893c3SAxel Dörfler fBootWorkspaceApplied(false), 165a10cf76eSAxel Dörfler fScreenMode(this), 166abc649b8SWaldemar Kornewald fTempScreenMode(this), 167abc649b8SWaldemar Kornewald fModified(false) 168a10cf76eSAxel Dörfler { 169a10cf76eSAxel Dörfler BScreen screen(this); 170a10cf76eSAxel Dörfler 17112580984SAxel Dörfler accelerant_device_info info; 172d1516993SAxel Dörfler if (screen.GetDeviceInfo(&info) == B_OK 173d1516993SAxel Dörfler && !strcasecmp(info.chipset, "VESA")) 17412580984SAxel Dörfler fIsVesa = true; 17512580984SAxel Dörfler 1765de171daSAxel Dörfler _UpdateOriginal(); 177a10cf76eSAxel Dörfler fActive = fSelected = fOriginal; 178a10cf76eSAxel Dörfler 1795a78744bSAxel Dörfler fSettings = settings; 1805a78744bSAxel Dörfler 1815a78744bSAxel Dörfler // we need the "Current Workspace" first to get its height 1825a78744bSAxel Dörfler 1835a78744bSAxel Dörfler BPopUpMenu *popUpMenu = new BPopUpMenu("Current Workspace", true, true); 184d1516993SAxel Dörfler fAllWorkspacesItem = new BMenuItem("All Workspaces", 185d1516993SAxel Dörfler new BMessage(WORKSPACE_CHECK_MSG)); 1865a78744bSAxel Dörfler popUpMenu->AddItem(fAllWorkspacesItem); 187d1516993SAxel Dörfler BMenuItem *item = new BMenuItem("Current Workspace", 188d1516993SAxel Dörfler new BMessage(WORKSPACE_CHECK_MSG)); 189b72c4836SAlexandre Deckner 1905a78744bSAxel Dörfler popUpMenu->AddItem(item); 19127c43a2dSRene Gollent fAllWorkspacesItem->SetMarked(true); 1925a78744bSAxel Dörfler 193b21d610eSAxel Dörfler BMenuField* workspaceMenuField = new BMenuField("WorkspaceMenu", NULL, 194b21d610eSAxel Dörfler popUpMenu, NULL); 1955a78744bSAxel Dörfler workspaceMenuField->ResizeToPreferred(); 196a10cf76eSAxel Dörfler 197a10cf76eSAxel Dörfler // box on the left with workspace count and monitor view 198a10cf76eSAxel Dörfler 199b21d610eSAxel Dörfler BBox* screenBox = new BBox("screen box"); 200b21d610eSAxel Dörfler BGroupLayout* layout = new BGroupLayout(B_VERTICAL, 10.0); 201b21d610eSAxel Dörfler layout->SetInsets(10, 10, 10, 10); 202b21d610eSAxel Dörfler screenBox->SetLayout(layout); 203a10cf76eSAxel Dörfler 204*12966d04SAxel Dörfler fMonitorInfo = new BStringView("monitor info", ""); 205*12966d04SAxel Dörfler screenBox->AddChild(fMonitorInfo); 206*12966d04SAxel Dörfler 207df3f5bacSStephan Aßmus fMonitorView = new MonitorView(BRect(0.0, 0.0, 80.0, 80.0), "monitor", 2086bda235aSStefano Ceccherini screen.Frame().IntegerWidth() + 1, screen.Frame().IntegerHeight() + 1); 209b21d610eSAxel Dörfler screenBox->AddChild(fMonitorView); 2105a78744bSAxel Dörfler 211b21d610eSAxel Dörfler /* 212b21d610eSAxel Dörfler BStringView* columnsView = new BStringView("", "Columns:"); 213b21d610eSAxel Dörfler columnsView->SetExplicitAlignment( 214b21d610eSAxel Dörfler BAlignment(B_ALIGN_RIGHT, B_ALIGN_VERTICAL_UNSET)); 215b21d610eSAxel Dörfler BStringView* rowsView = new BStringView("", "Rows:"); 216b21d610eSAxel Dörfler rowsView->SetExplicitAlignment( 217b21d610eSAxel Dörfler BAlignment(B_ALIGN_RIGHT, B_ALIGN_VERTICAL_UNSET)); 218b21d610eSAxel Dörfler */ 219b21d610eSAxel Dörfler 220b21d610eSAxel Dörfler fColumnsControl = new BTextControl("Columns:", "0", 221b21d610eSAxel Dörfler new BMessage(kMsgWorkspaceColumnsChanged)); 222b21d610eSAxel Dörfler fRowsControl = new BTextControl("Rows:", "0", 223b21d610eSAxel Dörfler new BMessage(kMsgWorkspaceRowsChanged)); 224b21d610eSAxel Dörfler 225b21d610eSAxel Dörfler screenBox->AddChild(BLayoutBuilder::Grid<>(5.0, 5.0) 226b21d610eSAxel Dörfler .Add(new BStringView("", "Workspaces"), 0, 0, 3) 227b21d610eSAxel Dörfler .AddTextControl(fColumnsControl, 0, 1, B_ALIGN_RIGHT) 228b21d610eSAxel Dörfler .AddGroup(B_HORIZONTAL, 0, 2, 1) 229b21d610eSAxel Dörfler .Add(_CreateColumnRowButton(true, false)) 230b21d610eSAxel Dörfler .Add(_CreateColumnRowButton(true, true)) 231b21d610eSAxel Dörfler .End() 232b21d610eSAxel Dörfler .AddTextControl(fRowsControl, 0, 2, B_ALIGN_RIGHT) 233b21d610eSAxel Dörfler .AddGroup(B_HORIZONTAL, 0, 2, 2) 234b21d610eSAxel Dörfler .Add(_CreateColumnRowButton(false, false)) 235b21d610eSAxel Dörfler .Add(_CreateColumnRowButton(false, true)) 236b21d610eSAxel Dörfler .End()); 237b21d610eSAxel Dörfler 238b21d610eSAxel Dörfler fBackgroundsButton = new BButton("BackgroundsButton", 239b21d610eSAxel Dörfler "Set Background" B_UTF8_ELLIPSIS, 240b21d610eSAxel Dörfler new BMessage(BUTTON_LAUNCH_BACKGROUNDS_MSG)); 241b21d610eSAxel Dörfler fBackgroundsButton->SetFontSize(be_plain_font->Size() * 0.9); 242b21d610eSAxel Dörfler screenBox->AddChild(fBackgroundsButton); 243a10cf76eSAxel Dörfler 244a10cf76eSAxel Dörfler // box on the right with screen resolution, etc. 245a10cf76eSAxel Dörfler 246b21d610eSAxel Dörfler BBox* controlsBox = new BBox("controls box"); 247b21d610eSAxel Dörfler controlsBox->SetLabel(workspaceMenuField); 248b21d610eSAxel Dörfler BView* outerControlsView = BLayoutBuilder::Group<>(B_VERTICAL, 10.0) 249b21d610eSAxel Dörfler .SetInsets(10, 10, 10, 10); 250b21d610eSAxel Dörfler controlsBox->AddChild(outerControlsView); 251a10cf76eSAxel Dörfler 252a10cf76eSAxel Dörfler fResolutionMenu = new BPopUpMenu("resolution", true, true); 253a10cf76eSAxel Dörfler 254a10cf76eSAxel Dörfler uint16 previousWidth = 0, previousHeight = 0; 255a10cf76eSAxel Dörfler for (int32 i = 0; i < fScreenMode.CountModes(); i++) { 256a10cf76eSAxel Dörfler screen_mode mode = fScreenMode.ModeAt(i); 257a10cf76eSAxel Dörfler 258a10cf76eSAxel Dörfler if (mode.width == previousWidth && mode.height == previousHeight) 259a10cf76eSAxel Dörfler continue; 260a10cf76eSAxel Dörfler 261a10cf76eSAxel Dörfler previousWidth = mode.width; 262a10cf76eSAxel Dörfler previousHeight = mode.height; 263a10cf76eSAxel Dörfler 264a10cf76eSAxel Dörfler BMessage *message = new BMessage(POP_RESOLUTION_MSG); 265a10cf76eSAxel Dörfler message->AddInt32("width", mode.width); 266a10cf76eSAxel Dörfler message->AddInt32("height", mode.height); 267a10cf76eSAxel Dörfler 268a10cf76eSAxel Dörfler BString name; 269a10cf76eSAxel Dörfler name << mode.width << " x " << mode.height; 270a10cf76eSAxel Dörfler 271a10cf76eSAxel Dörfler fResolutionMenu->AddItem(new BMenuItem(name.String(), message)); 272a10cf76eSAxel Dörfler } 273a10cf76eSAxel Dörfler 27429e8a73aSAxel Dörfler BRect rect(0.0, 0.0, 200.0, 15.0); 275df3f5bacSStephan Aßmus // fResolutionField needs to be at the correct 276df3f5bacSStephan Aßmus // left-top offset, because all other menu fields 277df3f5bacSStephan Aßmus // will be layouted relative to it 278b21d610eSAxel Dörfler fResolutionField = new BMenuField("ResolutionMenu", "Resolution:", 279b21d610eSAxel Dörfler fResolutionMenu, NULL); 280a10cf76eSAxel Dörfler 281a10cf76eSAxel Dörfler fColorsMenu = new BPopUpMenu("colors", true, true); 282a10cf76eSAxel Dörfler 283a10cf76eSAxel Dörfler for (int32 i = 0; i < kColorSpaceCount; i++) { 284a10cf76eSAxel Dörfler BMessage *message = new BMessage(POP_COLORS_MSG); 285a10cf76eSAxel Dörfler message->AddInt32("bits_per_pixel", kColorSpaces[i].bits_per_pixel); 286a10cf76eSAxel Dörfler message->AddInt32("space", kColorSpaces[i].space); 287a10cf76eSAxel Dörfler 288a10cf76eSAxel Dörfler fColorsMenu->AddItem(new BMenuItem(kColorSpaces[i].label, message)); 289a10cf76eSAxel Dörfler } 290a10cf76eSAxel Dörfler 291df3f5bacSStephan Aßmus rect.OffsetTo(B_ORIGIN); 292df3f5bacSStephan Aßmus 293b21d610eSAxel Dörfler fColorsField = new BMenuField("ColorsMenu", "Colors:", fColorsMenu, NULL); 294a10cf76eSAxel Dörfler 295a10cf76eSAxel Dörfler fRefreshMenu = new BPopUpMenu("refresh rate", true, true); 296a10cf76eSAxel Dörfler 29729e8a73aSAxel Dörfler BMessage *message; 29829e8a73aSAxel Dörfler 29929e8a73aSAxel Dörfler float min, max; 30029e8a73aSAxel Dörfler if (fScreenMode.GetRefreshLimits(fActive, min, max) && min == max) { 30129e8a73aSAxel Dörfler // This is a special case for drivers that only support a single 30229e8a73aSAxel Dörfler // frequency, like the VESA driver 30329e8a73aSAxel Dörfler BString name; 30429e8a73aSAxel Dörfler name << min << " Hz"; 30529e8a73aSAxel Dörfler 30629e8a73aSAxel Dörfler message = new BMessage(POP_REFRESH_MSG); 30729e8a73aSAxel Dörfler message->AddFloat("refresh", min); 30829e8a73aSAxel Dörfler 30929e8a73aSAxel Dörfler fRefreshMenu->AddItem(item = new BMenuItem(name.String(), message)); 31029e8a73aSAxel Dörfler item->SetEnabled(false); 31129e8a73aSAxel Dörfler } else { 312a10cf76eSAxel Dörfler for (int32 i = 0; i < kRefreshRateCount; ++i) { 313a10cf76eSAxel Dörfler BString name; 314a10cf76eSAxel Dörfler name << kRefreshRates[i] << " Hz"; 315a10cf76eSAxel Dörfler 31629e8a73aSAxel Dörfler message = new BMessage(POP_REFRESH_MSG); 317a10cf76eSAxel Dörfler message->AddFloat("refresh", kRefreshRates[i]); 318a10cf76eSAxel Dörfler 319a10cf76eSAxel Dörfler fRefreshMenu->AddItem(new BMenuItem(name.String(), message)); 320a10cf76eSAxel Dörfler } 321a10cf76eSAxel Dörfler 32229e8a73aSAxel Dörfler message = new BMessage(POP_OTHER_REFRESH_MSG); 323a10cf76eSAxel Dörfler 324a10cf76eSAxel Dörfler fOtherRefresh = new BMenuItem("Other" B_UTF8_ELLIPSIS, message); 325a10cf76eSAxel Dörfler fRefreshMenu->AddItem(fOtherRefresh); 32629e8a73aSAxel Dörfler } 327a10cf76eSAxel Dörfler 328b21d610eSAxel Dörfler fRefreshField = new BMenuField("RefreshMenu", "Refresh Rate:", 329b21d610eSAxel Dörfler fRefreshMenu, NULL); 330b21d610eSAxel Dörfler 33112580984SAxel Dörfler if (_IsVesa()) 33212580984SAxel Dörfler fRefreshField->Hide(); 333a10cf76eSAxel Dörfler 334a10cf76eSAxel Dörfler // enlarged area for multi-monitor settings 335a10cf76eSAxel Dörfler { 336a10cf76eSAxel Dörfler bool dummy; 337a10cf76eSAxel Dörfler uint32 dummy32; 338a10cf76eSAxel Dörfler bool multiMonSupport; 339a10cf76eSAxel Dörfler bool useLaptopPanelSupport; 340a10cf76eSAxel Dörfler bool tvStandardSupport; 341a10cf76eSAxel Dörfler 342a10cf76eSAxel Dörfler multiMonSupport = TestMultiMonSupport(&screen) == B_OK; 343a10cf76eSAxel Dörfler useLaptopPanelSupport = GetUseLaptopPanel(&screen, &dummy) == B_OK; 344a10cf76eSAxel Dörfler tvStandardSupport = GetTVStandard(&screen, &dummy32) == B_OK; 345a10cf76eSAxel Dörfler 346a10cf76eSAxel Dörfler // even if there is no support, we still create all controls 347a10cf76eSAxel Dörfler // to make sure we don't access NULL pointers later on 348a10cf76eSAxel Dörfler 349a10cf76eSAxel Dörfler fCombineMenu = new BPopUpMenu("CombineDisplays", true, true); 350a10cf76eSAxel Dörfler 351a10cf76eSAxel Dörfler for (int32 i = 0; i < kCombineModeCount; i++) { 352a10cf76eSAxel Dörfler message = new BMessage(POP_COMBINE_DISPLAYS_MSG); 353a10cf76eSAxel Dörfler message->AddInt32("mode", kCombineModes[i].mode); 354a10cf76eSAxel Dörfler 355d1516993SAxel Dörfler fCombineMenu->AddItem(new BMenuItem(kCombineModes[i].name, 356d1516993SAxel Dörfler message)); 357a10cf76eSAxel Dörfler } 358a10cf76eSAxel Dörfler 359b21d610eSAxel Dörfler fCombineField = new BMenuField("CombineMenu", 360b21d610eSAxel Dörfler "Combine Displays:", fCombineMenu, NULL); 361a10cf76eSAxel Dörfler 362a10cf76eSAxel Dörfler if (!multiMonSupport) 363df3f5bacSStephan Aßmus fCombineField->Hide(); 364a10cf76eSAxel Dörfler 365a10cf76eSAxel Dörfler fSwapDisplaysMenu = new BPopUpMenu("SwapDisplays", true, true); 366a10cf76eSAxel Dörfler 367a10cf76eSAxel Dörfler // !order is important - we rely that boolean value == idx 368a10cf76eSAxel Dörfler message = new BMessage(POP_SWAP_DISPLAYS_MSG); 369a10cf76eSAxel Dörfler message->AddBool("swap", false); 370a10cf76eSAxel Dörfler fSwapDisplaysMenu->AddItem(new BMenuItem("no", message)); 371a10cf76eSAxel Dörfler 372a10cf76eSAxel Dörfler message = new BMessage(POP_SWAP_DISPLAYS_MSG); 373a10cf76eSAxel Dörfler message->AddBool("swap", true); 374a10cf76eSAxel Dörfler fSwapDisplaysMenu->AddItem(new BMenuItem("yes", message)); 375a10cf76eSAxel Dörfler 376b21d610eSAxel Dörfler fSwapDisplaysField = new BMenuField("SwapMenu", "Swap Displays:", 377b21d610eSAxel Dörfler fSwapDisplaysMenu, NULL); 378a10cf76eSAxel Dörfler 379a10cf76eSAxel Dörfler if (!multiMonSupport) 380df3f5bacSStephan Aßmus fSwapDisplaysField->Hide(); 381a10cf76eSAxel Dörfler 382a10cf76eSAxel Dörfler fUseLaptopPanelMenu = new BPopUpMenu("UseLaptopPanel", true, true); 383a10cf76eSAxel Dörfler 384a10cf76eSAxel Dörfler // !order is important - we rely that boolean value == idx 385a10cf76eSAxel Dörfler message = new BMessage(POP_USE_LAPTOP_PANEL_MSG); 386a10cf76eSAxel Dörfler message->AddBool("use", false); 387a10cf76eSAxel Dörfler fUseLaptopPanelMenu->AddItem(new BMenuItem("if needed", message)); 388a10cf76eSAxel Dörfler 389a10cf76eSAxel Dörfler message = new BMessage(POP_USE_LAPTOP_PANEL_MSG); 390a10cf76eSAxel Dörfler message->AddBool("use", true); 391a10cf76eSAxel Dörfler fUseLaptopPanelMenu->AddItem(new BMenuItem("always", message)); 392a10cf76eSAxel Dörfler 393b21d610eSAxel Dörfler fUseLaptopPanelField = new BMenuField("UseLaptopPanel", 394b21d610eSAxel Dörfler "Use Laptop Panel:", fUseLaptopPanelMenu, NULL); 395a10cf76eSAxel Dörfler 396a10cf76eSAxel Dörfler if (!useLaptopPanelSupport) 397df3f5bacSStephan Aßmus fUseLaptopPanelField->Hide(); 398a10cf76eSAxel Dörfler 399a10cf76eSAxel Dörfler fTVStandardMenu = new BPopUpMenu("TVStandard", true, true); 400a10cf76eSAxel Dörfler 401a10cf76eSAxel Dörfler // arbitrary limit 402a10cf76eSAxel Dörfler uint32 i; 403a10cf76eSAxel Dörfler for (i = 0; i < 100; ++i) { 404a10cf76eSAxel Dörfler uint32 mode; 405a10cf76eSAxel Dörfler if (GetNthSupportedTVStandard(&screen, i, &mode) != B_OK) 406a10cf76eSAxel Dörfler break; 407a10cf76eSAxel Dörfler 408a10cf76eSAxel Dörfler BString name = tv_standard_to_string(mode); 409a10cf76eSAxel Dörfler 410a10cf76eSAxel Dörfler message = new BMessage(POP_TV_STANDARD_MSG); 411a10cf76eSAxel Dörfler message->AddInt32("tv_standard", mode); 412a10cf76eSAxel Dörfler 413a10cf76eSAxel Dörfler fTVStandardMenu->AddItem(new BMenuItem(name.String(), message)); 414a10cf76eSAxel Dörfler } 415a10cf76eSAxel Dörfler 416b21d610eSAxel Dörfler fTVStandardField = new BMenuField("tv standard", "Video Format:", 417b21d610eSAxel Dörfler fTVStandardMenu, NULL); 418df3f5bacSStephan Aßmus fTVStandardField->SetAlignment(B_ALIGN_RIGHT); 419a10cf76eSAxel Dörfler 420b21d610eSAxel Dörfler if (!tvStandardSupport || i == 0) 421df3f5bacSStephan Aßmus fTVStandardField->Hide(); 422a10cf76eSAxel Dörfler } 423a10cf76eSAxel Dörfler 424b21d610eSAxel Dörfler BView* controlsView = BLayoutBuilder::Grid<>(5.0, 5.0) 425b21d610eSAxel Dörfler .AddMenuField(fResolutionField, 0, 0, B_ALIGN_RIGHT) 426b21d610eSAxel Dörfler .AddMenuField(fColorsField, 0, 1, B_ALIGN_RIGHT) 427b21d610eSAxel Dörfler .AddMenuField(fRefreshField, 0, 2, B_ALIGN_RIGHT) 428b21d610eSAxel Dörfler .AddMenuField(fCombineField, 0, 3, B_ALIGN_RIGHT) 429b21d610eSAxel Dörfler .AddMenuField(fSwapDisplaysField, 0, 4, B_ALIGN_RIGHT) 430b21d610eSAxel Dörfler .AddMenuField(fUseLaptopPanelField, 0, 5, B_ALIGN_RIGHT) 431b21d610eSAxel Dörfler .AddMenuField(fTVStandardField, 0, 6, B_ALIGN_RIGHT); 432b21d610eSAxel Dörfler outerControlsView->AddChild(controlsView); 433df3f5bacSStephan Aßmus 434abc649b8SWaldemar Kornewald // TODO: we don't support getting the screen's preferred settings 435abc649b8SWaldemar Kornewald /* fDefaultsButton = new BButton(buttonRect, "DefaultsButton", "Defaults", 436b21d610eSAxel Dörfler new BMessage(BUTTON_DEFAULTS_MSG));*/ 437a10cf76eSAxel Dörfler 438b21d610eSAxel Dörfler fApplyButton = new BButton("ApplyButton", "Apply", 439df3f5bacSStephan Aßmus new BMessage(BUTTON_APPLY_MSG)); 440df3f5bacSStephan Aßmus fApplyButton->SetEnabled(false); 441b21d610eSAxel Dörfler outerControlsView->GetLayout()->AddItem(BSpaceLayoutItem::CreateGlue()); 442b21d610eSAxel Dörfler outerControlsView->AddChild(BLayoutBuilder::Group<>(B_HORIZONTAL) 443b21d610eSAxel Dörfler .AddGlue() 444b21d610eSAxel Dörfler .Add(fApplyButton)); 445b21d610eSAxel Dörfler 446b21d610eSAxel Dörfler fRevertButton = new BButton("RevertButton", "Revert", 447b21d610eSAxel Dörfler new BMessage(BUTTON_REVERT_MSG)); 448b21d610eSAxel Dörfler fRevertButton->SetEnabled(false); 449b21d610eSAxel Dörfler 450b21d610eSAxel Dörfler SetLayout(new BGroupLayout(B_VERTICAL, 10.0)); 451b21d610eSAxel Dörfler GetLayout()->View()->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 452b21d610eSAxel Dörfler 453b21d610eSAxel Dörfler BLayoutBuilder::Group<>(static_cast<BGroupLayout*>(GetLayout())) 454b21d610eSAxel Dörfler .SetInsets(10, 10, 10, 10) 455b21d610eSAxel Dörfler .AddGroup(B_HORIZONTAL, 10.0) 456b21d610eSAxel Dörfler .AddGroup(B_VERTICAL) 457b21d610eSAxel Dörfler .Add(screenBox) 458b21d610eSAxel Dörfler .End() 459b21d610eSAxel Dörfler .Add(controlsBox) 460b21d610eSAxel Dörfler .End() 461b21d610eSAxel Dörfler .AddGroup(B_HORIZONTAL, 10.0) 462b21d610eSAxel Dörfler .Add(fRevertButton) 463b21d610eSAxel Dörfler .AddGlue(); 464b21d610eSAxel Dörfler 465b21d610eSAxel Dörfler screenBox->Parent()->GetLayout()->AddItem(0, 466b21d610eSAxel Dörfler BSpaceLayoutItem::CreateVerticalStrut( 467b21d610eSAxel Dörfler controlsBox->TopBorderOffset() - 1)); 4685a78744bSAxel Dörfler 4695de171daSAxel Dörfler _UpdateControls(); 470*12966d04SAxel Dörfler _UpdateMonitor(); 471a10cf76eSAxel Dörfler } 472a10cf76eSAxel Dörfler 473a10cf76eSAxel Dörfler 474a10cf76eSAxel Dörfler ScreenWindow::~ScreenWindow() 475a10cf76eSAxel Dörfler { 476a10cf76eSAxel Dörfler delete fSettings; 477a10cf76eSAxel Dörfler } 478a10cf76eSAxel Dörfler 479a10cf76eSAxel Dörfler 480a10cf76eSAxel Dörfler bool 481a10cf76eSAxel Dörfler ScreenWindow::QuitRequested() 482a10cf76eSAxel Dörfler { 483a10cf76eSAxel Dörfler fSettings->SetWindowFrame(Frame()); 484199893c3SAxel Dörfler 485199893c3SAxel Dörfler // Write mode of workspace 0 (the boot workspace) to the vesa settings file 486199893c3SAxel Dörfler screen_mode vesaMode; 487199893c3SAxel Dörfler if (fBootWorkspaceApplied && fScreenMode.Get(vesaMode, 0) == B_OK) { 488199893c3SAxel Dörfler status_t status = _WriteVesaModeFile(vesaMode); 48912580984SAxel Dörfler if (status < B_OK) { 49012580984SAxel Dörfler BString warning = "Could not write VESA mode settings file:\n\t"; 49112580984SAxel Dörfler warning << strerror(status); 49212580984SAxel Dörfler (new BAlert("VesaAlert", warning.String(), "Okay", NULL, NULL, 49312580984SAxel Dörfler B_WIDTH_AS_USUAL, B_WARNING_ALERT))->Go(); 49412580984SAxel Dörfler } 49512580984SAxel Dörfler } 49612580984SAxel Dörfler 497a10cf76eSAxel Dörfler be_app->PostMessage(B_QUIT_REQUESTED); 498a10cf76eSAxel Dörfler 499a10cf76eSAxel Dörfler return BWindow::QuitRequested(); 500a10cf76eSAxel Dörfler } 501a10cf76eSAxel Dörfler 502a10cf76eSAxel Dörfler 5035de171daSAxel Dörfler /*! Update resolution list according to combine mode 5045de171daSAxel Dörfler (some resolution may not be combinable due to memory restrictions) 505a10cf76eSAxel Dörfler */ 506a10cf76eSAxel Dörfler void 5075de171daSAxel Dörfler ScreenWindow::_CheckResolutionMenu() 508a10cf76eSAxel Dörfler { 509a10cf76eSAxel Dörfler for (int32 i = 0; i < fResolutionMenu->CountItems(); i++) 510a10cf76eSAxel Dörfler fResolutionMenu->ItemAt(i)->SetEnabled(false); 511a10cf76eSAxel Dörfler 512a10cf76eSAxel Dörfler for (int32 i = 0; i < fScreenMode.CountModes(); i++) { 513a10cf76eSAxel Dörfler screen_mode mode = fScreenMode.ModeAt(i); 514a10cf76eSAxel Dörfler if (mode.combine != fSelected.combine) 515a10cf76eSAxel Dörfler continue; 516a10cf76eSAxel Dörfler 517a10cf76eSAxel Dörfler BString name; 518a10cf76eSAxel Dörfler name << mode.width << " x " << mode.height; 519a10cf76eSAxel Dörfler 520a10cf76eSAxel Dörfler BMenuItem *item = fResolutionMenu->FindItem(name.String()); 521a10cf76eSAxel Dörfler if (item != NULL) 522a10cf76eSAxel Dörfler item->SetEnabled(true); 523a10cf76eSAxel Dörfler } 524a10cf76eSAxel Dörfler } 525a10cf76eSAxel Dörfler 526a10cf76eSAxel Dörfler 5275de171daSAxel Dörfler /*! Update color and refresh options according to current mode 5285de171daSAxel Dörfler (a color space is made active if there is any mode with 5295de171daSAxel Dörfler given resolution and this colour space; same applies for 5305de171daSAxel Dörfler refresh rate, though "Other…" is always possible) 531a10cf76eSAxel Dörfler */ 532a10cf76eSAxel Dörfler void 5335de171daSAxel Dörfler ScreenWindow::_CheckColorMenu() 534a10cf76eSAxel Dörfler { 535a10cf76eSAxel Dörfler for (int32 i = 0; i < kColorSpaceCount; i++) { 536a10cf76eSAxel Dörfler bool supported = false; 537a10cf76eSAxel Dörfler 538a10cf76eSAxel Dörfler for (int32 j = 0; j < fScreenMode.CountModes(); j++) { 539a10cf76eSAxel Dörfler screen_mode mode = fScreenMode.ModeAt(j); 540a10cf76eSAxel Dörfler 541a10cf76eSAxel Dörfler if (fSelected.width == mode.width 542a10cf76eSAxel Dörfler && fSelected.height == mode.height 5435de171daSAxel Dörfler && (kColorSpaces[i].space == mode.space 5445de171daSAxel Dörfler // advertize 24 bit mode as 32 bit to avoid confusion 5455de171daSAxel Dörfler || (kColorSpaces[i].space == B_RGB32 5465de171daSAxel Dörfler && mode.space == B_RGB24)) 547a10cf76eSAxel Dörfler && fSelected.combine == mode.combine) { 548a10cf76eSAxel Dörfler supported = true; 549a10cf76eSAxel Dörfler break; 550a10cf76eSAxel Dörfler } 551a10cf76eSAxel Dörfler } 552a10cf76eSAxel Dörfler 553a10cf76eSAxel Dörfler BMenuItem* item = fColorsMenu->ItemAt(i); 554a10cf76eSAxel Dörfler if (item) 555a10cf76eSAxel Dörfler item->SetEnabled(supported); 556a10cf76eSAxel Dörfler } 557a10cf76eSAxel Dörfler } 558a10cf76eSAxel Dörfler 559a10cf76eSAxel Dörfler 5605de171daSAxel Dörfler /*! Enable/disable refresh options according to current mode. */ 561a10cf76eSAxel Dörfler void 5625de171daSAxel Dörfler ScreenWindow::_CheckRefreshMenu() 563a10cf76eSAxel Dörfler { 56429e8a73aSAxel Dörfler float min, max; 56529e8a73aSAxel Dörfler if (fScreenMode.GetRefreshLimits(fSelected, min, max) != B_OK || min == max) 56629e8a73aSAxel Dörfler return; 567a10cf76eSAxel Dörfler 56829e8a73aSAxel Dörfler for (int32 i = fRefreshMenu->CountItems(); i-- > 0;) { 56929e8a73aSAxel Dörfler BMenuItem* item = fRefreshMenu->ItemAt(i); 57029e8a73aSAxel Dörfler BMessage* message = item->Message(); 57129e8a73aSAxel Dörfler float refresh; 57229e8a73aSAxel Dörfler if (message != NULL && message->FindFloat("refresh", &refresh) == B_OK) 57329e8a73aSAxel Dörfler item->SetEnabled(refresh >= min && refresh <= max); 574a10cf76eSAxel Dörfler } 575a10cf76eSAxel Dörfler } 576a10cf76eSAxel Dörfler 577a10cf76eSAxel Dörfler 5785de171daSAxel Dörfler /*! Activate appropriate menu item according to selected refresh rate */ 579a10cf76eSAxel Dörfler void 5805de171daSAxel Dörfler ScreenWindow::_UpdateRefreshControl() 581a10cf76eSAxel Dörfler { 582a10cf76eSAxel Dörfler BString string; 583a10cf76eSAxel Dörfler refresh_rate_to_string(fSelected.refresh, string); 584a10cf76eSAxel Dörfler 585a10cf76eSAxel Dörfler BMenuItem* item = fRefreshMenu->FindItem(string.String()); 586a10cf76eSAxel Dörfler if (item) { 587a10cf76eSAxel Dörfler if (!item->IsMarked()) 588a10cf76eSAxel Dörfler item->SetMarked(true); 58929e8a73aSAxel Dörfler 590a10cf76eSAxel Dörfler // "Other…" items only contains a refresh rate when active 591e6b421a9SJérôme Duval fOtherRefresh->SetLabel("Other" B_UTF8_ELLIPSIS); 592a10cf76eSAxel Dörfler return; 593a10cf76eSAxel Dörfler } 594a10cf76eSAxel Dörfler 595a10cf76eSAxel Dörfler // this is a non-standard refresh rate 596a10cf76eSAxel Dörfler 597a10cf76eSAxel Dörfler fOtherRefresh->Message()->ReplaceFloat("refresh", fSelected.refresh); 598a10cf76eSAxel Dörfler fOtherRefresh->SetMarked(true); 599a10cf76eSAxel Dörfler 600a10cf76eSAxel Dörfler fRefreshMenu->Superitem()->SetLabel(string.String()); 601a10cf76eSAxel Dörfler 602a10cf76eSAxel Dörfler string.Append("/Other" B_UTF8_ELLIPSIS); 603a10cf76eSAxel Dörfler fOtherRefresh->SetLabel(string.String()); 604a10cf76eSAxel Dörfler } 605a10cf76eSAxel Dörfler 606a10cf76eSAxel Dörfler 607a10cf76eSAxel Dörfler void 6085de171daSAxel Dörfler ScreenWindow::_UpdateMonitorView() 609a10cf76eSAxel Dörfler { 610a10cf76eSAxel Dörfler BMessage updateMessage(UPDATE_DESKTOP_MSG); 611a10cf76eSAxel Dörfler updateMessage.AddInt32("width", fSelected.width); 612a10cf76eSAxel Dörfler updateMessage.AddInt32("height", fSelected.height); 613a10cf76eSAxel Dörfler 614a10cf76eSAxel Dörfler PostMessage(&updateMessage, fMonitorView); 615a10cf76eSAxel Dörfler } 616a10cf76eSAxel Dörfler 617a10cf76eSAxel Dörfler 618a10cf76eSAxel Dörfler void 6195de171daSAxel Dörfler ScreenWindow::_UpdateControls() 620a10cf76eSAxel Dörfler { 621b21d610eSAxel Dörfler _UpdateWorkspaceButtons(); 622b21d610eSAxel Dörfler 623a10cf76eSAxel Dörfler BMenuItem* item = fSwapDisplaysMenu->ItemAt((int32)fSelected.swap_displays); 624a10cf76eSAxel Dörfler if (item && !item->IsMarked()) 625a10cf76eSAxel Dörfler item->SetMarked(true); 626a10cf76eSAxel Dörfler 627a10cf76eSAxel Dörfler item = fUseLaptopPanelMenu->ItemAt((int32)fSelected.use_laptop_panel); 628a10cf76eSAxel Dörfler if (item && !item->IsMarked()) 629a10cf76eSAxel Dörfler item->SetMarked(true); 630a10cf76eSAxel Dörfler 631a10cf76eSAxel Dörfler for (int32 i = 0; i < fTVStandardMenu->CountItems(); i++) { 632a10cf76eSAxel Dörfler item = fTVStandardMenu->ItemAt(i); 633a10cf76eSAxel Dörfler 634a10cf76eSAxel Dörfler uint32 tvStandard; 635a10cf76eSAxel Dörfler item->Message()->FindInt32("tv_standard", (int32 *)&tvStandard); 636a10cf76eSAxel Dörfler if (tvStandard == fSelected.tv_standard) { 637a10cf76eSAxel Dörfler if (!item->IsMarked()) 638a10cf76eSAxel Dörfler item->SetMarked(true); 639a10cf76eSAxel Dörfler break; 640a10cf76eSAxel Dörfler } 641a10cf76eSAxel Dörfler } 642a10cf76eSAxel Dörfler 6435de171daSAxel Dörfler _CheckResolutionMenu(); 6445de171daSAxel Dörfler _CheckColorMenu(); 6455de171daSAxel Dörfler _CheckRefreshMenu(); 646a10cf76eSAxel Dörfler 647a10cf76eSAxel Dörfler BString string; 648a10cf76eSAxel Dörfler resolution_to_string(fSelected, string); 649a10cf76eSAxel Dörfler item = fResolutionMenu->FindItem(string.String()); 650a10cf76eSAxel Dörfler 651a10cf76eSAxel Dörfler if (item != NULL) { 652a10cf76eSAxel Dörfler if (!item->IsMarked()) 653a10cf76eSAxel Dörfler item->SetMarked(true); 654a10cf76eSAxel Dörfler } else { 655a10cf76eSAxel Dörfler // this is bad luck - if mode has been set via screen references, 656a10cf76eSAxel Dörfler // this case cannot occur; there are three possible solutions: 657a10cf76eSAxel Dörfler // 1. add a new resolution to list 658a10cf76eSAxel Dörfler // - we had to remove it as soon as a "valid" one is selected 659a10cf76eSAxel Dörfler // - we don't know which frequencies/bit depths are supported 660a10cf76eSAxel Dörfler // - as long as we haven't the GMT formula to create 661a10cf76eSAxel Dörfler // parameters for any resolution given, we cannot 662a10cf76eSAxel Dörfler // really set current mode - it's just not in the list 663a10cf76eSAxel Dörfler // 2. choose nearest resolution 664a10cf76eSAxel Dörfler // - probably a good idea, but implies coding and testing 665a10cf76eSAxel Dörfler // 3. choose lowest resolution 666a10cf76eSAxel Dörfler // - do you really think we are so lazy? yes, we are 667a10cf76eSAxel Dörfler item = fResolutionMenu->ItemAt(0); 668a10cf76eSAxel Dörfler if (item) 669a10cf76eSAxel Dörfler item->SetMarked(true); 670a10cf76eSAxel Dörfler 671a10cf76eSAxel Dörfler // okay - at least we set menu label to active resolution 672a10cf76eSAxel Dörfler fResolutionMenu->Superitem()->SetLabel(string.String()); 673a10cf76eSAxel Dörfler } 674a10cf76eSAxel Dörfler 675a10cf76eSAxel Dörfler // mark active combine mode 676a10cf76eSAxel Dörfler for (int32 i = 0; i < kCombineModeCount; i++) { 677a10cf76eSAxel Dörfler if (kCombineModes[i].mode == fSelected.combine) { 678a10cf76eSAxel Dörfler item = fCombineMenu->ItemAt(i); 679a10cf76eSAxel Dörfler if (item && !item->IsMarked()) 680a10cf76eSAxel Dörfler item->SetMarked(true); 681a10cf76eSAxel Dörfler break; 682a10cf76eSAxel Dörfler } 683a10cf76eSAxel Dörfler } 684a10cf76eSAxel Dörfler 685a10cf76eSAxel Dörfler item = fColorsMenu->ItemAt(0); 686a10cf76eSAxel Dörfler 687a10cf76eSAxel Dörfler for (int32 i = kColorSpaceCount; i-- > 0;) { 6885de171daSAxel Dörfler if (kColorSpaces[i].space == fSelected.space 6895de171daSAxel Dörfler || (kColorSpaces[i].space == B_RGB32 6905de171daSAxel Dörfler && fSelected.space == B_RGB24)) { 691a10cf76eSAxel Dörfler item = fColorsMenu->ItemAt(i); 692a10cf76eSAxel Dörfler break; 693a10cf76eSAxel Dörfler } 694a10cf76eSAxel Dörfler } 695a10cf76eSAxel Dörfler 696a10cf76eSAxel Dörfler if (item && !item->IsMarked()) 697a10cf76eSAxel Dörfler item->SetMarked(true); 698a10cf76eSAxel Dörfler 699a10cf76eSAxel Dörfler string.Truncate(0); 7005de171daSAxel Dörfler uint32 bitsPerPixel = fSelected.BitsPerPixel(); 7015de171daSAxel Dörfler // advertize 24 bit mode as 32 bit to avoid confusion 7025de171daSAxel Dörfler if (bitsPerPixel == 24) 7035de171daSAxel Dörfler bitsPerPixel = 32; 7045de171daSAxel Dörfler 7055de171daSAxel Dörfler string << bitsPerPixel << " Bits/Pixel"; 706a10cf76eSAxel Dörfler if (string != fColorsMenu->Superitem()->Label()) 707a10cf76eSAxel Dörfler fColorsMenu->Superitem()->SetLabel(string.String()); 708a10cf76eSAxel Dörfler 7095de171daSAxel Dörfler _UpdateMonitorView(); 7105de171daSAxel Dörfler _UpdateRefreshControl(); 711a10cf76eSAxel Dörfler 7125de171daSAxel Dörfler _CheckApplyEnabled(); 713a10cf76eSAxel Dörfler } 714a10cf76eSAxel Dörfler 715a10cf76eSAxel Dörfler 71612580984SAxel Dörfler /*! Reflect active mode in chosen settings */ 717a10cf76eSAxel Dörfler void 7185de171daSAxel Dörfler ScreenWindow::_UpdateActiveMode() 719a10cf76eSAxel Dörfler { 72012580984SAxel Dörfler // Usually, this function gets called after a mode 721a10cf76eSAxel Dörfler // has been set manually; still, as the graphics driver 722a10cf76eSAxel Dörfler // is free to fiddle with mode passed, we better ask 723a10cf76eSAxel Dörfler // what kind of mode we actually got 724a10cf76eSAxel Dörfler fScreenMode.Get(fActive); 725a10cf76eSAxel Dörfler fSelected = fActive; 726a10cf76eSAxel Dörfler 727*12966d04SAxel Dörfler _UpdateMonitor(); 7285de171daSAxel Dörfler _UpdateControls(); 729a10cf76eSAxel Dörfler } 730a10cf76eSAxel Dörfler 731a10cf76eSAxel Dörfler 732a10cf76eSAxel Dörfler void 733b21d610eSAxel Dörfler ScreenWindow::_UpdateWorkspaceButtons() 734b21d610eSAxel Dörfler { 735b21d610eSAxel Dörfler uint32 columns; 736b21d610eSAxel Dörfler uint32 rows; 737b21d610eSAxel Dörfler BPrivate::get_workspaces_layout(&columns, &rows); 738b21d610eSAxel Dörfler 739b21d610eSAxel Dörfler char text[32]; 740b21d610eSAxel Dörfler snprintf(text, sizeof(text), "%ld", columns); 741b21d610eSAxel Dörfler fColumnsControl->SetText(text); 742b21d610eSAxel Dörfler 743b21d610eSAxel Dörfler snprintf(text, sizeof(text), "%ld", rows); 744b21d610eSAxel Dörfler fRowsControl->SetText(text); 745b21d610eSAxel Dörfler 746b21d610eSAxel Dörfler _GetColumnRowButton(true, false)->SetEnabled(columns != 1 && rows != 32); 747b21d610eSAxel Dörfler _GetColumnRowButton(true, true)->SetEnabled((columns + 1) * rows < 32); 748b21d610eSAxel Dörfler _GetColumnRowButton(false, false)->SetEnabled(rows != 1 && columns != 32); 749b21d610eSAxel Dörfler _GetColumnRowButton(false, true)->SetEnabled(columns * (rows + 1) < 32); 750b21d610eSAxel Dörfler } 751b21d610eSAxel Dörfler 752b21d610eSAxel Dörfler 753b21d610eSAxel Dörfler void 754a10cf76eSAxel Dörfler ScreenWindow::ScreenChanged(BRect frame, color_space mode) 755a10cf76eSAxel Dörfler { 756a10cf76eSAxel Dörfler // move window on screen, if necessary 757a10cf76eSAxel Dörfler if (frame.right <= Frame().right 758a10cf76eSAxel Dörfler && frame.bottom <= Frame().bottom) { 759a10cf76eSAxel Dörfler MoveTo((frame.Width() - Frame().Width()) / 2, 760a10cf76eSAxel Dörfler (frame.Height() - Frame().Height()) / 2); 761a10cf76eSAxel Dörfler } 762a10cf76eSAxel Dörfler } 763a10cf76eSAxel Dörfler 764a10cf76eSAxel Dörfler 765a10cf76eSAxel Dörfler void 766a10cf76eSAxel Dörfler ScreenWindow::WorkspaceActivated(int32 workspace, bool state) 767a10cf76eSAxel Dörfler { 768abc649b8SWaldemar Kornewald fScreenMode.GetOriginalMode(fOriginal, workspace); 7695de171daSAxel Dörfler _UpdateActiveMode(); 770a10cf76eSAxel Dörfler 7716edaa0f6SStefano Ceccherini BMessage message(UPDATE_DESKTOP_COLOR_MSG); 7726edaa0f6SStefano Ceccherini PostMessage(&message, fMonitorView); 773a10cf76eSAxel Dörfler } 774a10cf76eSAxel Dörfler 775a10cf76eSAxel Dörfler 776a10cf76eSAxel Dörfler void 777a10cf76eSAxel Dörfler ScreenWindow::MessageReceived(BMessage* message) 778a10cf76eSAxel Dörfler { 779a10cf76eSAxel Dörfler switch (message->what) { 780a10cf76eSAxel Dörfler case WORKSPACE_CHECK_MSG: 7815de171daSAxel Dörfler _CheckApplyEnabled(); 782a10cf76eSAxel Dörfler break; 783a10cf76eSAxel Dörfler 784b21d610eSAxel Dörfler case kMsgWorkspaceLayoutChanged: 785a10cf76eSAxel Dörfler { 786b21d610eSAxel Dörfler int32 deltaX = 0; 787b21d610eSAxel Dörfler int32 deltaY = 0; 788b21d610eSAxel Dörfler message->FindInt32("delta_x", &deltaX); 789b21d610eSAxel Dörfler message->FindInt32("delta_y", &deltaY); 790b21d610eSAxel Dörfler 791b21d610eSAxel Dörfler if (deltaX == 0 && deltaY == 0) 792b21d610eSAxel Dörfler break; 793b21d610eSAxel Dörfler 794b21d610eSAxel Dörfler uint32 newColumns; 795b21d610eSAxel Dörfler uint32 newRows; 796b21d610eSAxel Dörfler BPrivate::get_workspaces_layout(&newColumns, &newRows); 797b21d610eSAxel Dörfler 798b21d610eSAxel Dörfler newColumns += deltaX; 799b21d610eSAxel Dörfler newRows += deltaY; 800b21d610eSAxel Dörfler BPrivate::set_workspaces_layout(newColumns, newRows); 801b21d610eSAxel Dörfler 802b21d610eSAxel Dörfler _UpdateWorkspaceButtons(); 8035de171daSAxel Dörfler _CheckApplyEnabled(); 804b21d610eSAxel Dörfler break; 805abc649b8SWaldemar Kornewald } 806b21d610eSAxel Dörfler 807b21d610eSAxel Dörfler case kMsgWorkspaceColumnsChanged: 808b21d610eSAxel Dörfler { 809b21d610eSAxel Dörfler uint32 newColumns = strtoul(fColumnsControl->Text(), NULL, 10); 810b21d610eSAxel Dörfler 811b21d610eSAxel Dörfler uint32 rows; 812b21d610eSAxel Dörfler BPrivate::get_workspaces_layout(NULL, &rows); 813b21d610eSAxel Dörfler BPrivate::set_workspaces_layout(newColumns, rows); 814b21d610eSAxel Dörfler 815b21d610eSAxel Dörfler _UpdateWorkspaceButtons(); 816b21d610eSAxel Dörfler _CheckApplyEnabled(); 817b21d610eSAxel Dörfler break; 818b21d610eSAxel Dörfler } 819b21d610eSAxel Dörfler 820b21d610eSAxel Dörfler case kMsgWorkspaceRowsChanged: 821b21d610eSAxel Dörfler { 822b21d610eSAxel Dörfler uint32 newRows = strtoul(fRowsControl->Text(), NULL, 10); 823b21d610eSAxel Dörfler 824b21d610eSAxel Dörfler uint32 columns; 825b21d610eSAxel Dörfler BPrivate::get_workspaces_layout(&columns, NULL); 826b21d610eSAxel Dörfler BPrivate::set_workspaces_layout(columns, newRows); 827b21d610eSAxel Dörfler 828b21d610eSAxel Dörfler _UpdateWorkspaceButtons(); 829b21d610eSAxel Dörfler _CheckApplyEnabled(); 830a10cf76eSAxel Dörfler break; 831a10cf76eSAxel Dörfler } 832a10cf76eSAxel Dörfler 833a10cf76eSAxel Dörfler case POP_RESOLUTION_MSG: 834a10cf76eSAxel Dörfler { 835a10cf76eSAxel Dörfler message->FindInt32("width", &fSelected.width); 836a10cf76eSAxel Dörfler message->FindInt32("height", &fSelected.height); 837a10cf76eSAxel Dörfler 8385de171daSAxel Dörfler _CheckColorMenu(); 8395de171daSAxel Dörfler _CheckRefreshMenu(); 840a10cf76eSAxel Dörfler 8415de171daSAxel Dörfler _UpdateMonitorView(); 8425de171daSAxel Dörfler _UpdateRefreshControl(); 843a10cf76eSAxel Dörfler 8445de171daSAxel Dörfler _CheckApplyEnabled(); 845a10cf76eSAxel Dörfler break; 846a10cf76eSAxel Dörfler } 847a10cf76eSAxel Dörfler 848a10cf76eSAxel Dörfler case POP_COLORS_MSG: 849a10cf76eSAxel Dörfler { 850a10cf76eSAxel Dörfler message->FindInt32("space", (int32 *)&fSelected.space); 851a10cf76eSAxel Dörfler 852a10cf76eSAxel Dörfler BString string; 853a10cf76eSAxel Dörfler string << fSelected.BitsPerPixel() << " Bits/Pixel"; 854a10cf76eSAxel Dörfler fColorsMenu->Superitem()->SetLabel(string.String()); 855a10cf76eSAxel Dörfler 8565de171daSAxel Dörfler _CheckApplyEnabled(); 857a10cf76eSAxel Dörfler break; 858a10cf76eSAxel Dörfler } 859a10cf76eSAxel Dörfler 860a10cf76eSAxel Dörfler case POP_REFRESH_MSG: 861a40498e2SWaldemar Kornewald { 862a10cf76eSAxel Dörfler message->FindFloat("refresh", &fSelected.refresh); 863a10cf76eSAxel Dörfler fOtherRefresh->SetLabel("Other" B_UTF8_ELLIPSIS); 864a10cf76eSAxel Dörfler // revert "Other…" label - it might have had a refresh rate prefix 865a10cf76eSAxel Dörfler 8665de171daSAxel Dörfler _CheckApplyEnabled(); 867a10cf76eSAxel Dörfler break; 868a40498e2SWaldemar Kornewald } 869a10cf76eSAxel Dörfler 870a10cf76eSAxel Dörfler case POP_OTHER_REFRESH_MSG: 871a10cf76eSAxel Dörfler { 87229e8a73aSAxel Dörfler // make sure menu shows something useful 8735de171daSAxel Dörfler _UpdateRefreshControl(); 874a10cf76eSAxel Dörfler 87529e8a73aSAxel Dörfler float min = 0, max = 999; 87629e8a73aSAxel Dörfler fScreenMode.GetRefreshLimits(fSelected, min, max); 87729e8a73aSAxel Dörfler if (min < gMinRefresh) 87829e8a73aSAxel Dörfler min = gMinRefresh; 87929e8a73aSAxel Dörfler if (max > gMaxRefresh) 88029e8a73aSAxel Dörfler max = gMaxRefresh; 88129e8a73aSAxel Dörfler 882c5d10f7aSAxel Dörfler RefreshWindow *fRefreshWindow = new RefreshWindow( 883c5d10f7aSAxel Dörfler fRefreshField->ConvertToScreen(B_ORIGIN), fSelected.refresh, min, max); 884a10cf76eSAxel Dörfler fRefreshWindow->Show(); 885a10cf76eSAxel Dörfler break; 886a10cf76eSAxel Dörfler } 887a10cf76eSAxel Dörfler 888a10cf76eSAxel Dörfler case SET_CUSTOM_REFRESH_MSG: 889a10cf76eSAxel Dörfler { 890a10cf76eSAxel Dörfler // user pressed "done" in "Other…" refresh dialog; 891a10cf76eSAxel Dörfler // select the refresh rate chosen 892a10cf76eSAxel Dörfler message->FindFloat("refresh", &fSelected.refresh); 893a10cf76eSAxel Dörfler 8945de171daSAxel Dörfler _UpdateRefreshControl(); 8955de171daSAxel Dörfler _CheckApplyEnabled(); 896a10cf76eSAxel Dörfler break; 897a10cf76eSAxel Dörfler } 898a10cf76eSAxel Dörfler 899a10cf76eSAxel Dörfler case POP_COMBINE_DISPLAYS_MSG: 900a10cf76eSAxel Dörfler { 901a10cf76eSAxel Dörfler // new combine mode has bee chosen 902a10cf76eSAxel Dörfler int32 mode; 903a10cf76eSAxel Dörfler if (message->FindInt32("mode", &mode) == B_OK) 904a10cf76eSAxel Dörfler fSelected.combine = (combine_mode)mode; 905a10cf76eSAxel Dörfler 9065de171daSAxel Dörfler _CheckResolutionMenu(); 9075de171daSAxel Dörfler _CheckApplyEnabled(); 908a10cf76eSAxel Dörfler break; 909a10cf76eSAxel Dörfler } 910a10cf76eSAxel Dörfler 911a10cf76eSAxel Dörfler case POP_SWAP_DISPLAYS_MSG: 912a10cf76eSAxel Dörfler message->FindBool("swap", &fSelected.swap_displays); 9135de171daSAxel Dörfler _CheckApplyEnabled(); 914a10cf76eSAxel Dörfler break; 915a10cf76eSAxel Dörfler 916a10cf76eSAxel Dörfler case POP_USE_LAPTOP_PANEL_MSG: 917a10cf76eSAxel Dörfler message->FindBool("use", &fSelected.use_laptop_panel); 9185de171daSAxel Dörfler _CheckApplyEnabled(); 919a10cf76eSAxel Dörfler break; 920a10cf76eSAxel Dörfler 921a10cf76eSAxel Dörfler case POP_TV_STANDARD_MSG: 922a10cf76eSAxel Dörfler message->FindInt32("tv_standard", (int32 *)&fSelected.tv_standard); 9235de171daSAxel Dörfler _CheckApplyEnabled(); 924a10cf76eSAxel Dörfler break; 925a10cf76eSAxel Dörfler 926df3f5bacSStephan Aßmus case BUTTON_LAUNCH_BACKGROUNDS_MSG: 9276f095d6aSRyan Leavengood if (be_roster->Launch(kBackgroundsSignature) == B_ALREADY_RUNNING) { 9286f095d6aSRyan Leavengood app_info info; 9296f095d6aSRyan Leavengood be_roster->GetAppInfo(kBackgroundsSignature, &info); 9306f095d6aSRyan Leavengood be_roster->ActivateApp(info.team); 9316f095d6aSRyan Leavengood } 932df3f5bacSStephan Aßmus break; 933df3f5bacSStephan Aßmus 934a10cf76eSAxel Dörfler case BUTTON_DEFAULTS_MSG: 935a10cf76eSAxel Dörfler { 9364be51fe3SWaldemar Kornewald // TODO: get preferred settings of screen 937a10cf76eSAxel Dörfler fSelected.width = 640; 938a10cf76eSAxel Dörfler fSelected.height = 480; 939a10cf76eSAxel Dörfler fSelected.space = B_CMAP8; 940a10cf76eSAxel Dörfler fSelected.refresh = 60.0; 941a10cf76eSAxel Dörfler fSelected.combine = kCombineDisable; 942a10cf76eSAxel Dörfler fSelected.swap_displays = false; 943a10cf76eSAxel Dörfler fSelected.use_laptop_panel = false; 944a10cf76eSAxel Dörfler fSelected.tv_standard = 0; 945a10cf76eSAxel Dörfler 946b21d610eSAxel Dörfler // TODO: workspace defaults 947abc649b8SWaldemar Kornewald 9485de171daSAxel Dörfler _UpdateControls(); 949a10cf76eSAxel Dörfler break; 950a10cf76eSAxel Dörfler } 951a10cf76eSAxel Dörfler 95210e9b12fSWaldemar Kornewald case BUTTON_UNDO_MSG: 953abc649b8SWaldemar Kornewald fTempScreenMode.Revert(); 9545de171daSAxel Dörfler _UpdateActiveMode(); 955abc649b8SWaldemar Kornewald break; 956abc649b8SWaldemar Kornewald 957abc649b8SWaldemar Kornewald case BUTTON_REVERT_MSG: 958abc649b8SWaldemar Kornewald { 959abc649b8SWaldemar Kornewald fModified = false; 960199893c3SAxel Dörfler fBootWorkspaceApplied = false; 961abc649b8SWaldemar Kornewald 962b21d610eSAxel Dörfler // ScreenMode::Revert() assumes that we first set the correct 963b21d610eSAxel Dörfler // number of workspaces 964b21d610eSAxel Dörfler 965b21d610eSAxel Dörfler BPrivate::set_workspaces_layout(fOriginalWorkspacesColumns, 966b21d610eSAxel Dörfler fOriginalWorkspacesRows); 967b21d610eSAxel Dörfler _UpdateWorkspaceButtons(); 968b21d610eSAxel Dörfler 969a10cf76eSAxel Dörfler fScreenMode.Revert(); 9705de171daSAxel Dörfler _UpdateActiveMode(); 971a10cf76eSAxel Dörfler break; 972abc649b8SWaldemar Kornewald } 973a10cf76eSAxel Dörfler 974a10cf76eSAxel Dörfler case BUTTON_APPLY_MSG: 9755de171daSAxel Dörfler _Apply(); 976a10cf76eSAxel Dörfler break; 977a10cf76eSAxel Dörfler 978abc649b8SWaldemar Kornewald case MAKE_INITIAL_MSG: 979abc649b8SWaldemar Kornewald // user pressed "keep" in confirmation dialog 980abc649b8SWaldemar Kornewald fModified = true; 9815de171daSAxel Dörfler _UpdateActiveMode(); 982a10cf76eSAxel Dörfler break; 983a10cf76eSAxel Dörfler 984a10cf76eSAxel Dörfler default: 985a10cf76eSAxel Dörfler BWindow::MessageReceived(message); 986a10cf76eSAxel Dörfler break; 987a10cf76eSAxel Dörfler } 988a10cf76eSAxel Dörfler } 989a10cf76eSAxel Dörfler 990a10cf76eSAxel Dörfler 99112580984SAxel Dörfler status_t 99212580984SAxel Dörfler ScreenWindow::_WriteVesaModeFile(const screen_mode& mode) const 99312580984SAxel Dörfler { 99412580984SAxel Dörfler BPath path; 99512580984SAxel Dörfler status_t status = find_directory(B_USER_SETTINGS_DIRECTORY, &path, true); 99612580984SAxel Dörfler if (status < B_OK) 99712580984SAxel Dörfler return status; 99812580984SAxel Dörfler 99912580984SAxel Dörfler path.Append("kernel/drivers"); 100012580984SAxel Dörfler status = create_directory(path.Path(), 0755); 100112580984SAxel Dörfler if (status < B_OK) 100212580984SAxel Dörfler return status; 100312580984SAxel Dörfler 100412580984SAxel Dörfler path.Append("vesa"); 100512580984SAxel Dörfler BFile file; 100612580984SAxel Dörfler status = file.SetTo(path.Path(), B_CREATE_FILE | B_WRITE_ONLY | B_ERASE_FILE); 100712580984SAxel Dörfler if (status < B_OK) 100812580984SAxel Dörfler return status; 100912580984SAxel Dörfler 101012580984SAxel Dörfler char buffer[256]; 101112580984SAxel Dörfler snprintf(buffer, sizeof(buffer), "mode %ld %ld %ld\n", 101212580984SAxel Dörfler mode.width, mode.height, mode.BitsPerPixel()); 101312580984SAxel Dörfler 101412580984SAxel Dörfler ssize_t bytesWritten = file.Write(buffer, strlen(buffer)); 101512580984SAxel Dörfler if (bytesWritten < B_OK) 101612580984SAxel Dörfler return bytesWritten; 101712580984SAxel Dörfler 101812580984SAxel Dörfler return B_OK; 101912580984SAxel Dörfler } 102012580984SAxel Dörfler 102112580984SAxel Dörfler 1022b21d610eSAxel Dörfler BButton* 1023b21d610eSAxel Dörfler ScreenWindow::_CreateColumnRowButton(bool columns, bool plus) 1024b21d610eSAxel Dörfler { 1025b21d610eSAxel Dörfler BMessage* message = new BMessage(kMsgWorkspaceLayoutChanged); 1026b21d610eSAxel Dörfler message->AddInt32("delta_x", columns ? (plus ? 1 : -1) : 0); 1027b21d610eSAxel Dörfler message->AddInt32("delta_y", !columns ? (plus ? 1 : -1) : 0); 1028b21d610eSAxel Dörfler 1029b21d610eSAxel Dörfler BButton* button = new BButton(plus ? "+" : "-", message); 1030b21d610eSAxel Dörfler button->SetFontSize(be_plain_font->Size() * 0.9); 1031b21d610eSAxel Dörfler 1032b21d610eSAxel Dörfler BSize size = button->MinSize(); 1033b21d610eSAxel Dörfler size.width = button->StringWidth("+") + 16; 1034b21d610eSAxel Dörfler button->SetExplicitMinSize(size); 1035b21d610eSAxel Dörfler button->SetExplicitMaxSize(size); 1036b21d610eSAxel Dörfler 1037b21d610eSAxel Dörfler fWorkspacesButtons[(columns ? 0 : 2) + (plus ? 1 : 0)] = button; 1038b21d610eSAxel Dörfler return button; 1039b21d610eSAxel Dörfler } 1040b21d610eSAxel Dörfler 1041b21d610eSAxel Dörfler 1042b21d610eSAxel Dörfler BButton* 1043b21d610eSAxel Dörfler ScreenWindow::_GetColumnRowButton(bool columns, bool plus) 1044b21d610eSAxel Dörfler { 1045b21d610eSAxel Dörfler return fWorkspacesButtons[(columns ? 0 : 2) + (plus ? 1 : 0)]; 1046b21d610eSAxel Dörfler } 1047b21d610eSAxel Dörfler 1048b21d610eSAxel Dörfler 1049a10cf76eSAxel Dörfler void 10505de171daSAxel Dörfler ScreenWindow::_CheckApplyEnabled() 1051a10cf76eSAxel Dörfler { 105227c43a2dSRene Gollent fApplyButton->SetEnabled(fSelected != fActive 105327c43a2dSRene Gollent || fAllWorkspacesItem->IsMarked()); 1054b21d610eSAxel Dörfler 1055b21d610eSAxel Dörfler uint32 columns; 1056b21d610eSAxel Dörfler uint32 rows; 1057b21d610eSAxel Dörfler BPrivate::get_workspaces_layout(&columns, &rows); 1058b21d610eSAxel Dörfler 1059b21d610eSAxel Dörfler fRevertButton->SetEnabled(columns != fOriginalWorkspacesColumns 1060b21d610eSAxel Dörfler || rows != fOriginalWorkspacesRows 10615de171daSAxel Dörfler || fSelected != fOriginal); 1062a10cf76eSAxel Dörfler } 1063a10cf76eSAxel Dörfler 1064a10cf76eSAxel Dörfler 1065a10cf76eSAxel Dörfler void 10665de171daSAxel Dörfler ScreenWindow::_UpdateOriginal() 1067abc649b8SWaldemar Kornewald { 1068b21d610eSAxel Dörfler BPrivate::get_workspaces_layout(&fOriginalWorkspacesColumns, 1069b21d610eSAxel Dörfler &fOriginalWorkspacesRows); 1070b21d610eSAxel Dörfler 1071abc649b8SWaldemar Kornewald fScreenMode.Get(fOriginal); 1072abc649b8SWaldemar Kornewald fScreenMode.UpdateOriginalModes(); 1073abc649b8SWaldemar Kornewald } 1074abc649b8SWaldemar Kornewald 1075abc649b8SWaldemar Kornewald 1076abc649b8SWaldemar Kornewald void 1077*12966d04SAxel Dörfler ScreenWindow::_UpdateMonitor() 1078*12966d04SAxel Dörfler { 1079*12966d04SAxel Dörfler monitor_info info; 1080*12966d04SAxel Dörfler float diagonalInches; 1081*12966d04SAxel Dörfler status_t status = fScreenMode.GetMonitorInfo(info, &diagonalInches); 1082*12966d04SAxel Dörfler 1083*12966d04SAxel Dörfler if (status != B_OK) { 1084*12966d04SAxel Dörfler if (!fMonitorInfo->IsHidden()) 1085*12966d04SAxel Dörfler fMonitorInfo->Hide(); 1086*12966d04SAxel Dörfler return; 1087*12966d04SAxel Dörfler } 1088*12966d04SAxel Dörfler 1089*12966d04SAxel Dörfler char text[256]; 1090*12966d04SAxel Dörfler snprintf(text, sizeof(text), "%s %s %g\"", info.vendor, info.name, 1091*12966d04SAxel Dörfler diagonalInches); 1092*12966d04SAxel Dörfler 1093*12966d04SAxel Dörfler fMonitorInfo->SetText(text); 1094*12966d04SAxel Dörfler 1095*12966d04SAxel Dörfler if (fMonitorInfo->IsHidden()) 1096*12966d04SAxel Dörfler fMonitorInfo->Show(); 1097*12966d04SAxel Dörfler } 1098*12966d04SAxel Dörfler 1099*12966d04SAxel Dörfler 1100*12966d04SAxel Dörfler void 11015de171daSAxel Dörfler ScreenWindow::_Apply() 1102a10cf76eSAxel Dörfler { 1103abc649b8SWaldemar Kornewald // make checkpoint, so we can undo these changes 1104abc649b8SWaldemar Kornewald fTempScreenMode.UpdateOriginalModes(); 110507184a9eSAxel Dörfler status_t status = fScreenMode.Set(fSelected); 110607184a9eSAxel Dörfler if (status == B_OK) { 1107abc649b8SWaldemar Kornewald // use the mode that has eventually been set and 1108abc649b8SWaldemar Kornewald // thus we know to be working; it can differ from 1109abc649b8SWaldemar Kornewald // the mode selected by user due to hardware limitation 1110abc649b8SWaldemar Kornewald display_mode newMode; 1111abc649b8SWaldemar Kornewald BScreen screen(this); 1112abc649b8SWaldemar Kornewald screen.GetMode(&newMode); 1113abc649b8SWaldemar Kornewald 1114abc649b8SWaldemar Kornewald if (fAllWorkspacesItem->IsMarked()) { 1115abc649b8SWaldemar Kornewald int32 originatingWorkspace = current_workspace(); 1116abc649b8SWaldemar Kornewald for (int32 i = 0; i < count_workspaces(); i++) { 1117abc649b8SWaldemar Kornewald if (i != originatingWorkspace) 1118abc649b8SWaldemar Kornewald screen.SetMode(i, &newMode, true); 1119abc649b8SWaldemar Kornewald } 1120199893c3SAxel Dörfler fBootWorkspaceApplied = true; 1121199893c3SAxel Dörfler } else { 1122199893c3SAxel Dörfler if (current_workspace() == 0) 1123199893c3SAxel Dörfler fBootWorkspaceApplied = true; 1124abc649b8SWaldemar Kornewald } 1125abc649b8SWaldemar Kornewald 1126a10cf76eSAxel Dörfler fActive = fSelected; 1127a10cf76eSAxel Dörfler 1128abc649b8SWaldemar Kornewald // TODO: only show alert when this is an unknown mode 1129a10cf76eSAxel Dörfler BWindow* window = new AlertWindow(this); 1130a10cf76eSAxel Dörfler window->Show(); 113107184a9eSAxel Dörfler } else { 113207184a9eSAxel Dörfler char message[256]; 113307184a9eSAxel Dörfler snprintf(message, sizeof(message), 113407184a9eSAxel Dörfler "The screen mode could not be set:\n\t%s\n", screen_errors(status)); 113507184a9eSAxel Dörfler BAlert* alert = new BAlert("Screen Alert", message, "Okay", NULL, NULL, 113607184a9eSAxel Dörfler B_WIDTH_AS_USUAL, B_WARNING_ALERT); 113707184a9eSAxel Dörfler alert->Go(); 1138a10cf76eSAxel Dörfler } 113907184a9eSAxel Dörfler } 114007184a9eSAxel Dörfler 1141