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 <MenuField.h> 3728d2323aSDaniel Martin #include <MenuItem.h> 38b21d610eSAxel Dörfler #include <Messenger.h> 39b21d610eSAxel Dörfler #include <Path.h> 40b21d610eSAxel Dörfler #include <PopUpMenu.h> 4128d2323aSDaniel Martin #include <Roster.h> 42b21d610eSAxel Dörfler #include <Screen.h> 43e1c88201SJohn Scipione #include <SpaceLayoutItem.h> 44a3fa81bdSJohn Scipione #include <Spinner.h> 45b21d610eSAxel Dörfler #include <String.h> 46b21d610eSAxel Dörfler #include <StringView.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 }; 8828d2323aSDaniel Martin static const int32 kColorSpaceCount = B_COUNT_OF(kColorSpaces); 89a10cf76eSAxel Dörfler 90a10cf76eSAxel Dörfler // list of standard refresh rates 91a796facfSAxel Dörfler static const int32 kRefreshRates[] = { 60, 70, 72, 75, 80, 85, 95, 100 }; 9228d2323aSDaniel Martin static const int32 kRefreshRateCount = B_COUNT_OF(kRefreshRates); 93a10cf76eSAxel Dörfler 94a10cf76eSAxel Dörfler // list of combine modes 95a10cf76eSAxel Dörfler static const struct { 96a10cf76eSAxel Dörfler combine_mode mode; 97a10cf76eSAxel Dörfler const char *name; 98a10cf76eSAxel Dörfler } kCombineModes[] = { 99c9e8f97aSAdrien Destugues { kCombineDisable, B_TRANSLATE("disable") }, 100c9e8f97aSAdrien Destugues { kCombineHorizontally, B_TRANSLATE("horizontally") }, 101c9e8f97aSAdrien Destugues { kCombineVertically, B_TRANSLATE("vertically") } 102a10cf76eSAxel Dörfler }; 10328d2323aSDaniel Martin static const int32 kCombineModeCount = B_COUNT_OF(kCombineModes); 10429e8a73aSAxel Dörfler 105a10cf76eSAxel Dörfler 106a10cf76eSAxel Dörfler static BString 107a10cf76eSAxel Dörfler tv_standard_to_string(uint32 mode) 108a10cf76eSAxel Dörfler { 109a10cf76eSAxel Dörfler switch (mode) { 110a10cf76eSAxel Dörfler case 0: return "disabled"; 111a10cf76eSAxel Dörfler case 1: return "NTSC"; 112a10cf76eSAxel Dörfler case 2: return "NTSC Japan"; 113a10cf76eSAxel Dörfler case 3: return "PAL BDGHI"; 114a10cf76eSAxel Dörfler case 4: return "PAL M"; 115a10cf76eSAxel Dörfler case 5: return "PAL N"; 116a10cf76eSAxel Dörfler case 6: return "SECAM"; 117a10cf76eSAxel Dörfler case 101: return "NTSC 443"; 118a10cf76eSAxel Dörfler case 102: return "PAL 60"; 119a10cf76eSAxel Dörfler case 103: return "PAL NC"; 120a10cf76eSAxel Dörfler default: 121a10cf76eSAxel Dörfler { 122a10cf76eSAxel Dörfler BString name; 123a10cf76eSAxel Dörfler name << "??? (" << mode << ")"; 124a10cf76eSAxel Dörfler 125a10cf76eSAxel Dörfler return name; 126a10cf76eSAxel Dörfler } 127a10cf76eSAxel Dörfler } 128a10cf76eSAxel Dörfler } 129a10cf76eSAxel Dörfler 130a10cf76eSAxel Dörfler 131a10cf76eSAxel Dörfler static void 132a10cf76eSAxel Dörfler resolution_to_string(screen_mode& mode, BString &string) 133a10cf76eSAxel Dörfler { 1343961af9fSHumdinger string.SetToFormat(B_TRANSLATE_COMMENT("%" B_PRId32" × %" B_PRId32, 1353961af9fSHumdinger "The '×' is the Unicode multiplication sign U+00D7"), 1363961af9fSHumdinger mode.width, mode.height); 137a10cf76eSAxel Dörfler } 138a10cf76eSAxel Dörfler 139a10cf76eSAxel Dörfler 140a10cf76eSAxel Dörfler static void 141a10cf76eSAxel Dörfler refresh_rate_to_string(float refresh, BString &string, 142a10cf76eSAxel Dörfler bool appendUnit = true, bool alwaysWithFraction = false) 143a10cf76eSAxel Dörfler { 1448bf23e3cSAxel Dörfler snprintf(string.LockBuffer(32), 32, "%.*g", refresh >= 100.0 ? 4 : 3, 1458bf23e3cSAxel Dörfler refresh); 146a10cf76eSAxel Dörfler string.UnlockBuffer(); 147a10cf76eSAxel Dörfler 148a10cf76eSAxel Dörfler if (appendUnit) 149551c9f15SSiarzhuk Zharski string << " " << B_TRANSLATE("Hz"); 150a10cf76eSAxel Dörfler } 151a10cf76eSAxel Dörfler 152a10cf76eSAxel Dörfler 15307184a9eSAxel Dörfler static const char* 15407184a9eSAxel Dörfler screen_errors(status_t status) 15507184a9eSAxel Dörfler { 15607184a9eSAxel Dörfler switch (status) { 15707184a9eSAxel Dörfler case B_ENTRY_NOT_FOUND: 158c9e8f97aSAdrien Destugues return B_TRANSLATE("Unknown mode"); 15907184a9eSAxel Dörfler // TODO: add more? 16007184a9eSAxel Dörfler 16107184a9eSAxel Dörfler default: 16207184a9eSAxel Dörfler return strerror(status); 16307184a9eSAxel Dörfler } 16407184a9eSAxel Dörfler } 16507184a9eSAxel Dörfler 16629e8a73aSAxel Dörfler 167a3fa81bdSJohn Scipione // #pragma mark - ScreenWindow 1683dfd20c0SStephan Aßmus 1693dfd20c0SStephan Aßmus 1705a78744bSAxel Dörfler ScreenWindow::ScreenWindow(ScreenSettings* settings) 171b21d610eSAxel Dörfler : 172560ff447SJonas Sundström BWindow(settings->WindowFrame(), B_TRANSLATE_SYSTEM_NAME("Screen"), 173958e0ca5SJohn Scipione B_TITLED_WINDOW, B_NOT_RESIZABLE | B_NOT_ZOOMABLE 174958e0ca5SJohn Scipione | B_AUTO_UPDATE_SIZE_LIMITS, B_ALL_WORKSPACES), 1753f953a72SAxel Dörfler fIsVesa(false), 176199893c3SAxel Dörfler fBootWorkspaceApplied(false), 1777e44de36SRene Gollent fOtherRefresh(NULL), 178294a85aaSRene Gollent fScreenMode(this), 17961c5c89bSAxel Dörfler fUndoScreenMode(this), 180abc649b8SWaldemar Kornewald fModified(false) 181a10cf76eSAxel Dörfler { 182a10cf76eSAxel Dörfler BScreen screen(this); 183a10cf76eSAxel Dörfler 18412580984SAxel Dörfler accelerant_device_info info; 185d1516993SAxel Dörfler if (screen.GetDeviceInfo(&info) == B_OK 186d1516993SAxel Dörfler && !strcasecmp(info.chipset, "VESA")) 18712580984SAxel Dörfler fIsVesa = true; 18812580984SAxel Dörfler 1895de171daSAxel Dörfler _UpdateOriginal(); 1901fc4cb1fSAxel Dörfler _BuildSupportedColorSpaces(); 191a10cf76eSAxel Dörfler fActive = fSelected = fOriginal; 192a10cf76eSAxel Dörfler 1935a78744bSAxel Dörfler fSettings = settings; 1945a78744bSAxel Dörfler 1955a78744bSAxel Dörfler // we need the "Current Workspace" first to get its height 1965a78744bSAxel Dörfler 197c9e8f97aSAdrien Destugues BPopUpMenu* popUpMenu = new BPopUpMenu(B_TRANSLATE("Current workspace"), 198c9e8f97aSAdrien Destugues true, true); 199c9e8f97aSAdrien Destugues fAllWorkspacesItem = new BMenuItem(B_TRANSLATE("All workspaces"), 200d1516993SAxel Dörfler new BMessage(WORKSPACE_CHECK_MSG)); 2015a78744bSAxel Dörfler popUpMenu->AddItem(fAllWorkspacesItem); 202c9e8f97aSAdrien Destugues BMenuItem *item = new BMenuItem(B_TRANSLATE("Current workspace"), 203d1516993SAxel Dörfler new BMessage(WORKSPACE_CHECK_MSG)); 204b72c4836SAlexandre Deckner 2055a78744bSAxel Dörfler popUpMenu->AddItem(item); 20627c43a2dSRene Gollent fAllWorkspacesItem->SetMarked(true); 2075a78744bSAxel Dörfler 208b21d610eSAxel Dörfler BMenuField* workspaceMenuField = new BMenuField("WorkspaceMenu", NULL, 20910dfe897SAxel Dörfler popUpMenu); 2105a78744bSAxel Dörfler workspaceMenuField->ResizeToPreferred(); 211a10cf76eSAxel Dörfler 212a10cf76eSAxel Dörfler // box on the left with workspace count and monitor view 213a10cf76eSAxel Dörfler 214ef046e3bSJohn Scipione fScreenBox = new BBox("screen box"); 215ef046e3bSJohn Scipione BGroupView* groupView = new BGroupView(B_VERTICAL, B_USE_SMALL_SPACING); 216ef046e3bSJohn Scipione fScreenBox->AddChild(groupView); 217ef046e3bSJohn Scipione fScreenBox->SetLabel("placeholder"); 218ef046e3bSJohn Scipione // Needed for layouting, will be replaced with screen name/size 219ef046e3bSJohn Scipione groupView->GroupLayout()->SetInsets(B_USE_DEFAULT_SPACING, 220ef046e3bSJohn Scipione B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING); 221a10cf76eSAxel Dörfler 222ef046e3bSJohn Scipione fDeviceInfo = new BStringView("device info", ""); 2238b46ee25SAdrien Destugues fDeviceInfo->SetAlignment(B_ALIGN_CENTER); 224ef046e3bSJohn Scipione groupView->AddChild(fDeviceInfo); 2258b46ee25SAdrien Destugues 2268bf216d6SAxel Dörfler float scaling = std::max(1.0f, be_plain_font->Size() / 12.0f); 2278bf216d6SAxel Dörfler fMonitorView = new MonitorView(BRect(0.0, 0.0, 80.0 * scaling, 2288bf216d6SAxel Dörfler 80.0 * scaling), "monitor", screen.Frame().IntegerWidth() + 1, 229c9e8f97aSAdrien Destugues screen.Frame().IntegerHeight() + 1); 230ef046e3bSJohn Scipione fMonitorView->SetToolTip(B_TRANSLATE("Set background" B_UTF8_ELLIPSIS)); 231ef046e3bSJohn Scipione groupView->AddChild(fMonitorView); 2325a78744bSAxel Dörfler 233ef046e3bSJohn Scipione // brightness slider 234ef046e3bSJohn Scipione fBrightnessSlider = new BSlider("brightness", B_TRANSLATE("Brightness:"), 235ef046e3bSJohn Scipione NULL, 0, 255, B_HORIZONTAL); 236ef046e3bSJohn Scipione groupView->AddChild(fBrightnessSlider); 237ef046e3bSJohn Scipione 238ef046e3bSJohn Scipione if (screen.GetBrightness(&fOriginalBrightness) == B_OK) { 239ef046e3bSJohn Scipione fBrightnessSlider->SetModificationMessage( 240ef046e3bSJohn Scipione new BMessage(SLIDER_BRIGHTNESS_MSG)); 241ef046e3bSJohn Scipione fBrightnessSlider->SetValue(fOriginalBrightness * 255); 242ef046e3bSJohn Scipione } else { 243ef046e3bSJohn Scipione // The driver does not support changing the brightness, 244ef046e3bSJohn Scipione // so hide the slider 245ef046e3bSJohn Scipione fBrightnessSlider->Hide(); 246ef046e3bSJohn Scipione fOriginalBrightness = -1; 247ef046e3bSJohn Scipione } 248ef046e3bSJohn Scipione 249ef046e3bSJohn Scipione // box on the left below the screen box with workspaces 250ef046e3bSJohn Scipione 251ef046e3bSJohn Scipione BBox* workspacesBox = new BBox("workspaces box"); 252ef046e3bSJohn Scipione workspacesBox->SetLabel(B_TRANSLATE("Workspaces")); 253ef046e3bSJohn Scipione 254ef046e3bSJohn Scipione BGroupLayout* workspacesLayout = new BGroupLayout(B_VERTICAL); 255ef046e3bSJohn Scipione workspacesLayout->SetInsets(B_USE_DEFAULT_SPACING, 256ef046e3bSJohn Scipione be_control_look->DefaultItemSpacing() * 2, B_USE_DEFAULT_SPACING, 257ef046e3bSJohn Scipione B_USE_DEFAULT_SPACING); 258ef046e3bSJohn Scipione workspacesBox->SetLayout(workspacesLayout); 259e1c88201SJohn Scipione 260a3fa81bdSJohn Scipione fColumnsControl = new BSpinner("columns", B_TRANSLATE("Columns:"), 261b21d610eSAxel Dörfler new BMessage(kMsgWorkspaceColumnsChanged)); 262a3fa81bdSJohn Scipione fColumnsControl->SetAlignment(B_ALIGN_RIGHT); 263a3fa81bdSJohn Scipione fColumnsControl->SetRange(1, 32); 264b21d610eSAxel Dörfler 265a3fa81bdSJohn Scipione fRowsControl = new BSpinner("rows", B_TRANSLATE("Rows:"), 266a3fa81bdSJohn Scipione new BMessage(kMsgWorkspaceRowsChanged)); 267a3fa81bdSJohn Scipione fRowsControl->SetAlignment(B_ALIGN_RIGHT); 268a3fa81bdSJohn Scipione fRowsControl->SetRange(1, 32); 269a3fa81bdSJohn Scipione 270a3fa81bdSJohn Scipione uint32 columns; 271a3fa81bdSJohn Scipione uint32 rows; 272a3fa81bdSJohn Scipione BPrivate::get_workspaces_layout(&columns, &rows); 273a3fa81bdSJohn Scipione fColumnsControl->SetValue(columns); 274a3fa81bdSJohn Scipione fRowsControl->SetValue(rows); 275a3fa81bdSJohn Scipione 276ef046e3bSJohn Scipione workspacesBox->AddChild(BLayoutBuilder::Group<>() 277e1c88201SJohn Scipione .AddGroup(B_VERTICAL, B_USE_SMALL_SPACING) 2784dcc9761SJohn Scipione .AddGroup(B_HORIZONTAL, 0) 2794dcc9761SJohn Scipione .AddGlue() 280a3fa81bdSJohn Scipione .AddGrid(B_USE_DEFAULT_SPACING, B_USE_SMALL_SPACING) 281e1c88201SJohn Scipione // columns 282e1c88201SJohn Scipione .Add(fColumnsControl->CreateLabelLayoutItem(), 0, 0) 283a3fa81bdSJohn Scipione .Add(fColumnsControl->CreateTextViewLayoutItem(), 1, 0) 284e1c88201SJohn Scipione // rows 285e1c88201SJohn Scipione .Add(fRowsControl->CreateLabelLayoutItem(), 0, 1) 286a3fa81bdSJohn Scipione .Add(fRowsControl->CreateTextViewLayoutItem(), 1, 1) 287b21d610eSAxel Dörfler .End() 2884dcc9761SJohn Scipione .AddGlue() 2894dcc9761SJohn Scipione .End() 29025fd5c7bSAlex Wilson .End() 29125fd5c7bSAlex Wilson .View()); 292b21d610eSAxel Dörfler 293ef046e3bSJohn Scipione // put workspaces slider in a vertical group with a half space above so 294ef046e3bSJohn Scipione // if hidden you won't see the extra space. 295ef046e3bSJohn Scipione BView* workspacesView = BLayoutBuilder::Group<>(B_VERTICAL, 0) 296ef046e3bSJohn Scipione .AddStrut(B_USE_HALF_ITEM_SPACING) 297ef046e3bSJohn Scipione .Add(workspacesBox) 298ef046e3bSJohn Scipione .View(); 299a10cf76eSAxel Dörfler 300a10cf76eSAxel Dörfler // box on the right with screen resolution, etc. 301a10cf76eSAxel Dörfler 302b21d610eSAxel Dörfler BBox* controlsBox = new BBox("controls box"); 303b21d610eSAxel Dörfler controlsBox->SetLabel(workspaceMenuField); 3046048f541SJohn Scipione BGroupView* outerControlsView = new BGroupView(B_VERTICAL); 3056048f541SJohn Scipione outerControlsView->GroupLayout()->SetInsets(B_USE_DEFAULT_SPACING, 3066048f541SJohn Scipione B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING, B_USE_DEFAULT_SPACING); 307b21d610eSAxel Dörfler controlsBox->AddChild(outerControlsView); 308a10cf76eSAxel Dörfler 3094c28b3f1SPulkoMandy menu_layout layout = B_ITEMS_IN_COLUMN; 310a10cf76eSAxel Dörfler 3114c28b3f1SPulkoMandy // There are modes in the list with the same resolution but different bpp or refresh rates. 3124c28b3f1SPulkoMandy // We don't want to take these into account when computing the menu layout, so we need to 3134c28b3f1SPulkoMandy // count how many entries we will really have in the menu. 3144c28b3f1SPulkoMandy int fullModeCount = fScreenMode.CountModes(); 3154c28b3f1SPulkoMandy int modeCount = 0; 3164c28b3f1SPulkoMandy int index = 0; 31766ab1666SAxel Dörfler uint16 maxWidth = 0; 31866ab1666SAxel Dörfler uint16 maxHeight = 0; 31966ab1666SAxel Dörfler uint16 previousWidth = 0; 32066ab1666SAxel Dörfler uint16 previousHeight = 0; 3214c28b3f1SPulkoMandy for (int32 i = 0; i < fullModeCount; i++) { 3224c28b3f1SPulkoMandy screen_mode mode = fScreenMode.ModeAt(i); 3234c28b3f1SPulkoMandy 3244c28b3f1SPulkoMandy if (mode.width == previousWidth && mode.height == previousHeight) 3254c28b3f1SPulkoMandy continue; 3264c28b3f1SPulkoMandy modeCount++; 3274c28b3f1SPulkoMandy previousWidth = mode.width; 3284c28b3f1SPulkoMandy previousHeight = mode.height; 3294c28b3f1SPulkoMandy if (maxWidth < mode.width) 3304c28b3f1SPulkoMandy maxWidth = mode.width; 3314c28b3f1SPulkoMandy if (maxHeight < mode.height) 3324c28b3f1SPulkoMandy maxHeight = mode.height; 3334c28b3f1SPulkoMandy } 3344c28b3f1SPulkoMandy 3354c28b3f1SPulkoMandy if (modeCount > 16) 3364c28b3f1SPulkoMandy layout = B_ITEMS_IN_MATRIX; 3374c28b3f1SPulkoMandy 3384c28b3f1SPulkoMandy fResolutionMenu = new BPopUpMenu("resolution", true, true, layout); 3394c28b3f1SPulkoMandy 3404c28b3f1SPulkoMandy // Compute the size we should allocate to each item in the menu 3414c28b3f1SPulkoMandy BRect itemRect; 3424c28b3f1SPulkoMandy if (layout == B_ITEMS_IN_MATRIX) { 3434c28b3f1SPulkoMandy BFont menuFont; 3444c28b3f1SPulkoMandy font_height fontHeight; 3454c28b3f1SPulkoMandy 3464c28b3f1SPulkoMandy fResolutionMenu->GetFont(&menuFont); 3474c28b3f1SPulkoMandy menuFont.GetHeight(&fontHeight); 3484c28b3f1SPulkoMandy itemRect.left = itemRect.top = 0; 3494c28b3f1SPulkoMandy itemRect.bottom = fontHeight.ascent + fontHeight.descent + 4; 3504c28b3f1SPulkoMandy itemRect.right = menuFont.StringWidth("99999x99999") + 16; 3514c28b3f1SPulkoMandy rows = modeCount / 3 + 1; 3524c28b3f1SPulkoMandy } 3534c28b3f1SPulkoMandy 3544c28b3f1SPulkoMandy index = 0; 3554c28b3f1SPulkoMandy for (int32 i = 0; i < fullModeCount; i++) { 356a10cf76eSAxel Dörfler screen_mode mode = fScreenMode.ModeAt(i); 357a10cf76eSAxel Dörfler 358a10cf76eSAxel Dörfler if (mode.width == previousWidth && mode.height == previousHeight) 359a10cf76eSAxel Dörfler continue; 360a10cf76eSAxel Dörfler 361a10cf76eSAxel Dörfler previousWidth = mode.width; 362a10cf76eSAxel Dörfler previousHeight = mode.height; 363a10cf76eSAxel Dörfler 364a10cf76eSAxel Dörfler BMessage* message = new BMessage(POP_RESOLUTION_MSG); 365a10cf76eSAxel Dörfler message->AddInt32("width", mode.width); 366a10cf76eSAxel Dörfler message->AddInt32("height", mode.height); 367a10cf76eSAxel Dörfler 368a10cf76eSAxel Dörfler BString name; 3693961af9fSHumdinger name.SetToFormat(B_TRANSLATE_COMMENT("%" B_PRId32" × %" B_PRId32, 3703961af9fSHumdinger "The '×' is the Unicode multiplication sign U+00D7"), 3713961af9fSHumdinger mode.width, mode.height); 372a10cf76eSAxel Dörfler 3734c28b3f1SPulkoMandy if (layout == B_ITEMS_IN_COLUMN) 374a10cf76eSAxel Dörfler fResolutionMenu->AddItem(new BMenuItem(name.String(), message)); 3754c28b3f1SPulkoMandy else { 3764c28b3f1SPulkoMandy int y = index % rows; 3774c28b3f1SPulkoMandy int x = index / rows; 3784c28b3f1SPulkoMandy itemRect.OffsetTo(x * itemRect.Width(), y * itemRect.Height()); 3794c28b3f1SPulkoMandy fResolutionMenu->AddItem(new BMenuItem(name.String(), message), itemRect); 3804c28b3f1SPulkoMandy } 3814c28b3f1SPulkoMandy 3824c28b3f1SPulkoMandy index++; 383a10cf76eSAxel Dörfler } 384a10cf76eSAxel Dörfler 38566ab1666SAxel Dörfler fMonitorView->SetMaxResolution(maxWidth, maxHeight); 38666ab1666SAxel Dörfler 387c9e8f97aSAdrien Destugues fResolutionField = new BMenuField("ResolutionMenu", 38810dfe897SAxel Dörfler B_TRANSLATE("Resolution:"), fResolutionMenu); 3896048f541SJohn Scipione fResolutionField->SetAlignment(B_ALIGN_RIGHT); 390a10cf76eSAxel Dörfler 391551c9f15SSiarzhuk Zharski fColorsMenu = new BPopUpMenu("colors", true, false); 392a10cf76eSAxel Dörfler 393a10cf76eSAxel Dörfler for (int32 i = 0; i < kColorSpaceCount; i++) { 3941fc4cb1fSAxel Dörfler if ((fSupportedColorSpaces & (1 << i)) == 0) 3951fc4cb1fSAxel Dörfler continue; 3961fc4cb1fSAxel Dörfler 397a10cf76eSAxel Dörfler BMessage* message = new BMessage(POP_COLORS_MSG); 398a10cf76eSAxel Dörfler message->AddInt32("bits_per_pixel", kColorSpaces[i].bits_per_pixel); 399a10cf76eSAxel Dörfler message->AddInt32("space", kColorSpaces[i].space); 400a10cf76eSAxel Dörfler 4011fc4cb1fSAxel Dörfler BMenuItem* item = new BMenuItem(kColorSpaces[i].label, message); 4021fc4cb1fSAxel Dörfler if (kColorSpaces[i].space == screen.ColorSpace()) 4031fc4cb1fSAxel Dörfler fUserSelectedColorSpace = item; 4041fc4cb1fSAxel Dörfler 4051fc4cb1fSAxel Dörfler fColorsMenu->AddItem(item); 406a10cf76eSAxel Dörfler } 407a10cf76eSAxel Dörfler 408c9e8f97aSAdrien Destugues fColorsField = new BMenuField("ColorsMenu", B_TRANSLATE("Colors:"), 40910dfe897SAxel Dörfler fColorsMenu); 4106048f541SJohn Scipione fColorsField->SetAlignment(B_ALIGN_RIGHT); 411a10cf76eSAxel Dörfler 412551c9f15SSiarzhuk Zharski fRefreshMenu = new BPopUpMenu("refresh rate", true, true); 413a10cf76eSAxel Dörfler 41429e8a73aSAxel Dörfler float min, max; 415ec495b30SRene Gollent if (fScreenMode.GetRefreshLimits(fActive, min, max) != B_OK) { 416ec495b30SRene Gollent // if we couldn't obtain the refresh limits, reset to the default 417ec495b30SRene Gollent // range. Constraints from detected monitors will fine-tune this 418ec495b30SRene Gollent // later. 419ec495b30SRene Gollent min = kRefreshRates[0]; 420ec495b30SRene Gollent max = kRefreshRates[kRefreshRateCount - 1]; 421ec495b30SRene Gollent } 422ec495b30SRene Gollent 423ec495b30SRene Gollent if (min == max) { 42429e8a73aSAxel Dörfler // This is a special case for drivers that only support a single 42529e8a73aSAxel Dörfler // frequency, like the VESA driver 42629e8a73aSAxel Dörfler BString name; 4277e44de36SRene Gollent refresh_rate_to_string(min, name); 428cf076964SRene Gollent BMessage *message = new BMessage(POP_REFRESH_MSG); 429cf076964SRene Gollent message->AddFloat("refresh", min); 430cf076964SRene Gollent BMenuItem *item = new BMenuItem(name.String(), message); 4310efb8b66SJerome Duval fRefreshMenu->AddItem(item); 43229e8a73aSAxel Dörfler item->SetEnabled(false); 43329e8a73aSAxel Dörfler } else { 43470a2b1b5SAxel Dörfler monitor_info info; 43570a2b1b5SAxel Dörfler if (fScreenMode.GetMonitorInfo(info) == B_OK) { 43670a2b1b5SAxel Dörfler min = max_c(info.min_vertical_frequency, min); 43770a2b1b5SAxel Dörfler max = min_c(info.max_vertical_frequency, max); 43870a2b1b5SAxel Dörfler } 43970a2b1b5SAxel Dörfler 440a10cf76eSAxel Dörfler for (int32 i = 0; i < kRefreshRateCount; ++i) { 44170a2b1b5SAxel Dörfler if (kRefreshRates[i] < min || kRefreshRates[i] > max) 44270a2b1b5SAxel Dörfler continue; 44370a2b1b5SAxel Dörfler 444a10cf76eSAxel Dörfler BString name; 445551c9f15SSiarzhuk Zharski name << kRefreshRates[i] << " " << B_TRANSLATE("Hz"); 446a10cf76eSAxel Dörfler 4470efb8b66SJerome Duval BMessage *message = new BMessage(POP_REFRESH_MSG); 448a10cf76eSAxel Dörfler message->AddFloat("refresh", kRefreshRates[i]); 449a10cf76eSAxel Dörfler 450a10cf76eSAxel Dörfler fRefreshMenu->AddItem(new BMenuItem(name.String(), message)); 451a10cf76eSAxel Dörfler } 452a10cf76eSAxel Dörfler 453c9e8f97aSAdrien Destugues fOtherRefresh = new BMenuItem(B_TRANSLATE("Other" B_UTF8_ELLIPSIS), 4540efb8b66SJerome Duval new BMessage(POP_OTHER_REFRESH_MSG)); 455a10cf76eSAxel Dörfler fRefreshMenu->AddItem(fOtherRefresh); 45629e8a73aSAxel Dörfler } 457a10cf76eSAxel Dörfler 458c9e8f97aSAdrien Destugues fRefreshField = new BMenuField("RefreshMenu", B_TRANSLATE("Refresh rate:"), 45910dfe897SAxel Dörfler fRefreshMenu); 4606048f541SJohn Scipione fRefreshField->SetAlignment(B_ALIGN_RIGHT); 461b21d610eSAxel Dörfler 46212580984SAxel Dörfler if (_IsVesa()) 46312580984SAxel Dörfler fRefreshField->Hide(); 464a10cf76eSAxel Dörfler 465a10cf76eSAxel Dörfler // enlarged area for multi-monitor settings 466a10cf76eSAxel Dörfler { 467a10cf76eSAxel Dörfler bool dummy; 468a10cf76eSAxel Dörfler uint32 dummy32; 469a10cf76eSAxel Dörfler bool multiMonSupport; 470a10cf76eSAxel Dörfler bool useLaptopPanelSupport; 471a10cf76eSAxel Dörfler bool tvStandardSupport; 472a10cf76eSAxel Dörfler 473a10cf76eSAxel Dörfler multiMonSupport = TestMultiMonSupport(&screen) == B_OK; 474a10cf76eSAxel Dörfler useLaptopPanelSupport = GetUseLaptopPanel(&screen, &dummy) == B_OK; 475a10cf76eSAxel Dörfler tvStandardSupport = GetTVStandard(&screen, &dummy32) == B_OK; 476a10cf76eSAxel Dörfler 477a10cf76eSAxel Dörfler // even if there is no support, we still create all controls 478a10cf76eSAxel Dörfler // to make sure we don't access NULL pointers later on 479a10cf76eSAxel Dörfler 480551c9f15SSiarzhuk Zharski fCombineMenu = new BPopUpMenu("CombineDisplays", 481c9e8f97aSAdrien Destugues true, true); 482a10cf76eSAxel Dörfler 483a10cf76eSAxel Dörfler for (int32 i = 0; i < kCombineModeCount; i++) { 4840efb8b66SJerome Duval BMessage *message = new BMessage(POP_COMBINE_DISPLAYS_MSG); 485a10cf76eSAxel Dörfler message->AddInt32("mode", kCombineModes[i].mode); 486a10cf76eSAxel Dörfler 487d1516993SAxel Dörfler fCombineMenu->AddItem(new BMenuItem(kCombineModes[i].name, 488d1516993SAxel Dörfler message)); 489a10cf76eSAxel Dörfler } 490a10cf76eSAxel Dörfler 491b21d610eSAxel Dörfler fCombineField = new BMenuField("CombineMenu", 49210dfe897SAxel Dörfler B_TRANSLATE("Combine displays:"), fCombineMenu); 4936048f541SJohn Scipione fCombineField->SetAlignment(B_ALIGN_RIGHT); 494a10cf76eSAxel Dörfler 495a10cf76eSAxel Dörfler if (!multiMonSupport) 496df3f5bacSStephan Aßmus fCombineField->Hide(); 497a10cf76eSAxel Dörfler 498551c9f15SSiarzhuk Zharski fSwapDisplaysMenu = new BPopUpMenu("SwapDisplays", 499c9e8f97aSAdrien Destugues true, true); 500a10cf76eSAxel Dörfler 501a10cf76eSAxel Dörfler // !order is important - we rely that boolean value == idx 5020efb8b66SJerome Duval BMessage *message = new BMessage(POP_SWAP_DISPLAYS_MSG); 503a10cf76eSAxel Dörfler message->AddBool("swap", false); 504c9e8f97aSAdrien Destugues fSwapDisplaysMenu->AddItem(new BMenuItem(B_TRANSLATE("no"), message)); 505a10cf76eSAxel Dörfler 506a10cf76eSAxel Dörfler message = new BMessage(POP_SWAP_DISPLAYS_MSG); 507a10cf76eSAxel Dörfler message->AddBool("swap", true); 508c9e8f97aSAdrien Destugues fSwapDisplaysMenu->AddItem(new BMenuItem(B_TRANSLATE("yes"), message)); 509a10cf76eSAxel Dörfler 510c9e8f97aSAdrien Destugues fSwapDisplaysField = new BMenuField("SwapMenu", 51110dfe897SAxel Dörfler B_TRANSLATE("Swap displays:"), fSwapDisplaysMenu); 5126048f541SJohn Scipione fSwapDisplaysField->SetAlignment(B_ALIGN_RIGHT); 513a10cf76eSAxel Dörfler 514a10cf76eSAxel Dörfler if (!multiMonSupport) 515df3f5bacSStephan Aßmus fSwapDisplaysField->Hide(); 516a10cf76eSAxel Dörfler 517551c9f15SSiarzhuk Zharski fUseLaptopPanelMenu = new BPopUpMenu("UseLaptopPanel", 518c9e8f97aSAdrien Destugues true, true); 519a10cf76eSAxel Dörfler 520a10cf76eSAxel Dörfler // !order is important - we rely that boolean value == idx 521a10cf76eSAxel Dörfler message = new BMessage(POP_USE_LAPTOP_PANEL_MSG); 522a10cf76eSAxel Dörfler message->AddBool("use", false); 523c9e8f97aSAdrien Destugues fUseLaptopPanelMenu->AddItem(new BMenuItem(B_TRANSLATE("if needed"), 524c9e8f97aSAdrien Destugues message)); 525a10cf76eSAxel Dörfler 526a10cf76eSAxel Dörfler message = new BMessage(POP_USE_LAPTOP_PANEL_MSG); 527a10cf76eSAxel Dörfler message->AddBool("use", true); 528c9e8f97aSAdrien Destugues fUseLaptopPanelMenu->AddItem(new BMenuItem(B_TRANSLATE("always"), 529c9e8f97aSAdrien Destugues message)); 530a10cf76eSAxel Dörfler 531b21d610eSAxel Dörfler fUseLaptopPanelField = new BMenuField("UseLaptopPanel", 53210dfe897SAxel Dörfler B_TRANSLATE("Use laptop panel:"), fUseLaptopPanelMenu); 5336048f541SJohn Scipione fUseLaptopPanelField->SetAlignment(B_ALIGN_RIGHT); 534a10cf76eSAxel Dörfler 535a10cf76eSAxel Dörfler if (!useLaptopPanelSupport) 536df3f5bacSStephan Aßmus fUseLaptopPanelField->Hide(); 537a10cf76eSAxel Dörfler 538551c9f15SSiarzhuk Zharski fTVStandardMenu = new BPopUpMenu("TVStandard", true, true); 539a10cf76eSAxel Dörfler 540a10cf76eSAxel Dörfler // arbitrary limit 541a10cf76eSAxel Dörfler uint32 i; 542a10cf76eSAxel Dörfler for (i = 0; i < 100; ++i) { 543a10cf76eSAxel Dörfler uint32 mode; 544a10cf76eSAxel Dörfler if (GetNthSupportedTVStandard(&screen, i, &mode) != B_OK) 545a10cf76eSAxel Dörfler break; 546a10cf76eSAxel Dörfler 547a10cf76eSAxel Dörfler BString name = tv_standard_to_string(mode); 548a10cf76eSAxel Dörfler 549a10cf76eSAxel Dörfler message = new BMessage(POP_TV_STANDARD_MSG); 550a10cf76eSAxel Dörfler message->AddInt32("tv_standard", mode); 551a10cf76eSAxel Dörfler 552a10cf76eSAxel Dörfler fTVStandardMenu->AddItem(new BMenuItem(name.String(), message)); 553a10cf76eSAxel Dörfler } 554a10cf76eSAxel Dörfler 555c9e8f97aSAdrien Destugues fTVStandardField = new BMenuField("tv standard", 55610dfe897SAxel Dörfler B_TRANSLATE("Video format:"), fTVStandardMenu); 557df3f5bacSStephan Aßmus fTVStandardField->SetAlignment(B_ALIGN_RIGHT); 558a10cf76eSAxel Dörfler 559b21d610eSAxel Dörfler if (!tvStandardSupport || i == 0) 560df3f5bacSStephan Aßmus fTVStandardField->Hide(); 561a10cf76eSAxel Dörfler } 562a10cf76eSAxel Dörfler 56325fd5c7bSAlex Wilson BLayoutBuilder::Group<>(outerControlsView) 5646048f541SJohn Scipione .AddGrid(B_USE_DEFAULT_SPACING, B_USE_SMALL_SPACING) 5656048f541SJohn Scipione .Add(fResolutionField->CreateLabelLayoutItem(), 0, 0) 5666048f541SJohn Scipione .Add(fResolutionField->CreateMenuBarLayoutItem(), 1, 0) 5676048f541SJohn Scipione .Add(fColorsField->CreateLabelLayoutItem(), 0, 1) 5686048f541SJohn Scipione .Add(fColorsField->CreateMenuBarLayoutItem(), 1, 1) 5696048f541SJohn Scipione .Add(fRefreshField->CreateLabelLayoutItem(), 0, 2) 5706048f541SJohn Scipione .Add(fRefreshField->CreateMenuBarLayoutItem(), 1, 2) 5716048f541SJohn Scipione .Add(fCombineField->CreateLabelLayoutItem(), 0, 3) 5726048f541SJohn Scipione .Add(fCombineField->CreateMenuBarLayoutItem(), 1, 3) 5736048f541SJohn Scipione .Add(fSwapDisplaysField->CreateLabelLayoutItem(), 0, 4) 5746048f541SJohn Scipione .Add(fSwapDisplaysField->CreateMenuBarLayoutItem(), 1, 4) 5756048f541SJohn Scipione .Add(fUseLaptopPanelField->CreateLabelLayoutItem(), 0, 5) 5766048f541SJohn Scipione .Add(fUseLaptopPanelField->CreateMenuBarLayoutItem(), 1, 5) 5776048f541SJohn Scipione .Add(fTVStandardField->CreateLabelLayoutItem(), 0, 6) 5786048f541SJohn Scipione .Add(fTVStandardField->CreateMenuBarLayoutItem(), 1, 6) 57925fd5c7bSAlex Wilson .End(); 580df3f5bacSStephan Aßmus 581abc649b8SWaldemar Kornewald // TODO: we don't support getting the screen's preferred settings 582abc649b8SWaldemar Kornewald /* fDefaultsButton = new BButton(buttonRect, "DefaultsButton", "Defaults", 583b21d610eSAxel Dörfler new BMessage(BUTTON_DEFAULTS_MSG));*/ 584a10cf76eSAxel Dörfler 585c9e8f97aSAdrien Destugues fApplyButton = new BButton("ApplyButton", B_TRANSLATE("Apply"), 586df3f5bacSStephan Aßmus new BMessage(BUTTON_APPLY_MSG)); 587df3f5bacSStephan Aßmus fApplyButton->SetEnabled(false); 58825fd5c7bSAlex Wilson BLayoutBuilder::Group<>(outerControlsView) 589b21d610eSAxel Dörfler .AddGlue() 59025fd5c7bSAlex Wilson .AddGroup(B_HORIZONTAL) 59125fd5c7bSAlex Wilson .AddGlue() 59225fd5c7bSAlex Wilson .Add(fApplyButton); 593b21d610eSAxel Dörfler 594c9e8f97aSAdrien Destugues fRevertButton = new BButton("RevertButton", B_TRANSLATE("Revert"), 595b21d610eSAxel Dörfler new BMessage(BUTTON_REVERT_MSG)); 596b21d610eSAxel Dörfler fRevertButton->SetEnabled(false); 597b21d610eSAxel Dörfler 5984666484fSJohn Scipione BLayoutBuilder::Group<>(this, B_VERTICAL, B_USE_DEFAULT_SPACING) 5994666484fSJohn Scipione .AddGroup(B_HORIZONTAL) 600a2cb1737SAdrien Destugues .AddGroup(B_VERTICAL, 0, 1) 601ef046e3bSJohn Scipione .AddStrut(floorf(controlsBox->TopBorderOffset() 602ef046e3bSJohn Scipione - fScreenBox->TopBorderOffset())) 603ef046e3bSJohn Scipione .Add(fScreenBox) 604ef046e3bSJohn Scipione .Add(workspacesView) 60583cc66b3SJohn Scipione .End() 6063a2b67b5SAdrien Destugues .AddGroup(B_VERTICAL, 0, 1) 607a2cb1737SAdrien Destugues .Add(controlsBox, 2) 6083a2b67b5SAdrien Destugues .End() 609b21d610eSAxel Dörfler .End() 6104666484fSJohn Scipione .AddGroup(B_HORIZONTAL, B_USE_DEFAULT_SPACING) 611b21d610eSAxel Dörfler .Add(fRevertButton) 6124666484fSJohn Scipione .AddGlue() 6134666484fSJohn Scipione .End() 614d0ac6099SHumdinger .SetInsets(B_USE_WINDOW_SPACING); 615b21d610eSAxel Dörfler 6165de171daSAxel Dörfler _UpdateControls(); 61712966d04SAxel Dörfler _UpdateMonitor(); 6188bf216d6SAxel Dörfler 6198bf216d6SAxel Dörfler MoveOnScreen(); 620a10cf76eSAxel Dörfler } 621a10cf76eSAxel Dörfler 622a10cf76eSAxel Dörfler 623a10cf76eSAxel Dörfler ScreenWindow::~ScreenWindow() 624a10cf76eSAxel Dörfler { 625a10cf76eSAxel Dörfler delete fSettings; 626a10cf76eSAxel Dörfler } 627a10cf76eSAxel Dörfler 628a10cf76eSAxel Dörfler 629a10cf76eSAxel Dörfler bool 630a10cf76eSAxel Dörfler ScreenWindow::QuitRequested() 631a10cf76eSAxel Dörfler { 632a10cf76eSAxel Dörfler fSettings->SetWindowFrame(Frame()); 633199893c3SAxel Dörfler 634199893c3SAxel Dörfler // Write mode of workspace 0 (the boot workspace) to the vesa settings file 635199893c3SAxel Dörfler screen_mode vesaMode; 636199893c3SAxel Dörfler if (fBootWorkspaceApplied && fScreenMode.Get(vesaMode, 0) == B_OK) { 637199893c3SAxel Dörfler status_t status = _WriteVesaModeFile(vesaMode); 63812580984SAxel Dörfler if (status < B_OK) { 639c9e8f97aSAdrien Destugues BString warning = B_TRANSLATE("Could not write VESA mode settings" 640c9e8f97aSAdrien Destugues " file:\n\t"); 64112580984SAxel Dörfler warning << strerror(status); 642aed35104SHumdinger BAlert* alert = new BAlert(B_TRANSLATE("Warning"), 643aed35104SHumdinger warning.String(), B_TRANSLATE("OK"), NULL, 644aed35104SHumdinger NULL, B_WIDTH_AS_USUAL, B_WARNING_ALERT); 645aed35104SHumdinger alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE); 646aed35104SHumdinger alert->Go(); 64712580984SAxel Dörfler } 64812580984SAxel Dörfler } 64912580984SAxel Dörfler 650a10cf76eSAxel Dörfler be_app->PostMessage(B_QUIT_REQUESTED); 651a10cf76eSAxel Dörfler 652a10cf76eSAxel Dörfler return BWindow::QuitRequested(); 653a10cf76eSAxel Dörfler } 654a10cf76eSAxel Dörfler 655a10cf76eSAxel Dörfler 6565de171daSAxel Dörfler /*! Update resolution list according to combine mode 6571fc4cb1fSAxel Dörfler (some resolutions may not be combinable due to memory restrictions). 658a10cf76eSAxel Dörfler */ 659a10cf76eSAxel Dörfler void 6605de171daSAxel Dörfler ScreenWindow::_CheckResolutionMenu() 661a10cf76eSAxel Dörfler { 662a10cf76eSAxel Dörfler for (int32 i = 0; i < fResolutionMenu->CountItems(); i++) 663a10cf76eSAxel Dörfler fResolutionMenu->ItemAt(i)->SetEnabled(false); 664a10cf76eSAxel Dörfler 665a10cf76eSAxel Dörfler for (int32 i = 0; i < fScreenMode.CountModes(); i++) { 666a10cf76eSAxel Dörfler screen_mode mode = fScreenMode.ModeAt(i); 667a10cf76eSAxel Dörfler if (mode.combine != fSelected.combine) 668a10cf76eSAxel Dörfler continue; 669a10cf76eSAxel Dörfler 670a10cf76eSAxel Dörfler BString name; 6713961af9fSHumdinger name.SetToFormat(B_TRANSLATE_COMMENT("%" B_PRId32" × %" B_PRId32, 6723961af9fSHumdinger "The '×' is the Unicode multiplication sign U+00D7"), 6733961af9fSHumdinger mode.width, mode.height); 674a10cf76eSAxel Dörfler 675a10cf76eSAxel Dörfler BMenuItem *item = fResolutionMenu->FindItem(name.String()); 676a10cf76eSAxel Dörfler if (item != NULL) 677a10cf76eSAxel Dörfler item->SetEnabled(true); 678a10cf76eSAxel Dörfler } 679a10cf76eSAxel Dörfler } 680a10cf76eSAxel Dörfler 681a10cf76eSAxel Dörfler 6825de171daSAxel Dörfler /*! Update color and refresh options according to current mode 6835de171daSAxel Dörfler (a color space is made active if there is any mode with 6845de171daSAxel Dörfler given resolution and this colour space; same applies for 6855de171daSAxel Dörfler refresh rate, though "Other…" is always possible) 686a10cf76eSAxel Dörfler */ 687a10cf76eSAxel Dörfler void 6885de171daSAxel Dörfler ScreenWindow::_CheckColorMenu() 689a10cf76eSAxel Dörfler { 6901fc4cb1fSAxel Dörfler int32 supportsAnything = false; 6911fc4cb1fSAxel Dörfler int32 index = 0; 6921fc4cb1fSAxel Dörfler 693a10cf76eSAxel Dörfler for (int32 i = 0; i < kColorSpaceCount; i++) { 6941fc4cb1fSAxel Dörfler if ((fSupportedColorSpaces & (1 << i)) == 0) 6951fc4cb1fSAxel Dörfler continue; 6961fc4cb1fSAxel Dörfler 697a10cf76eSAxel Dörfler bool supported = false; 698a10cf76eSAxel Dörfler 699a10cf76eSAxel Dörfler for (int32 j = 0; j < fScreenMode.CountModes(); j++) { 700a10cf76eSAxel Dörfler screen_mode mode = fScreenMode.ModeAt(j); 701a10cf76eSAxel Dörfler 702a10cf76eSAxel Dörfler if (fSelected.width == mode.width 703a10cf76eSAxel Dörfler && fSelected.height == mode.height 7041fc4cb1fSAxel Dörfler && kColorSpaces[i].space == mode.space 705a10cf76eSAxel Dörfler && fSelected.combine == mode.combine) { 7061fc4cb1fSAxel Dörfler supportsAnything = true; 707a10cf76eSAxel Dörfler supported = true; 708a10cf76eSAxel Dörfler break; 709a10cf76eSAxel Dörfler } 710a10cf76eSAxel Dörfler } 711a10cf76eSAxel Dörfler 7121fc4cb1fSAxel Dörfler BMenuItem* item = fColorsMenu->ItemAt(index++); 713a10cf76eSAxel Dörfler if (item) 714a10cf76eSAxel Dörfler item->SetEnabled(supported); 715a10cf76eSAxel Dörfler } 7161fc4cb1fSAxel Dörfler 7171fc4cb1fSAxel Dörfler fColorsField->SetEnabled(supportsAnything); 7181fc4cb1fSAxel Dörfler 7191fc4cb1fSAxel Dörfler if (!supportsAnything) 7201fc4cb1fSAxel Dörfler return; 7211fc4cb1fSAxel Dörfler 7221fc4cb1fSAxel Dörfler // Make sure a valid item is selected 7231fc4cb1fSAxel Dörfler 7241fc4cb1fSAxel Dörfler BMenuItem* item = fColorsMenu->FindMarked(); 7251fc4cb1fSAxel Dörfler bool changed = false; 7261fc4cb1fSAxel Dörfler 7271fc4cb1fSAxel Dörfler if (item != fUserSelectedColorSpace) { 7281fc4cb1fSAxel Dörfler if (fUserSelectedColorSpace != NULL 7291fc4cb1fSAxel Dörfler && fUserSelectedColorSpace->IsEnabled()) { 7301fc4cb1fSAxel Dörfler fUserSelectedColorSpace->SetMarked(true); 7311fc4cb1fSAxel Dörfler item = fUserSelectedColorSpace; 7321fc4cb1fSAxel Dörfler changed = true; 7331fc4cb1fSAxel Dörfler } 7341fc4cb1fSAxel Dörfler } 7351fc4cb1fSAxel Dörfler if (item != NULL && !item->IsEnabled()) { 7361fc4cb1fSAxel Dörfler // find the next best item 7371fc4cb1fSAxel Dörfler int32 index = fColorsMenu->IndexOf(item); 7381fc4cb1fSAxel Dörfler bool found = false; 7391fc4cb1fSAxel Dörfler 7401fc4cb1fSAxel Dörfler for (int32 i = index + 1; i < fColorsMenu->CountItems(); i++) { 7411fc4cb1fSAxel Dörfler item = fColorsMenu->ItemAt(i); 7421fc4cb1fSAxel Dörfler if (item->IsEnabled()) { 7431fc4cb1fSAxel Dörfler found = true; 7441fc4cb1fSAxel Dörfler break; 7451fc4cb1fSAxel Dörfler } 7461fc4cb1fSAxel Dörfler } 7471fc4cb1fSAxel Dörfler if (!found) { 7481fc4cb1fSAxel Dörfler // search backwards as well 7491fc4cb1fSAxel Dörfler for (int32 i = index - 1; i >= 0; i--) { 7501fc4cb1fSAxel Dörfler item = fColorsMenu->ItemAt(i); 7511fc4cb1fSAxel Dörfler if (item->IsEnabled()) 7521fc4cb1fSAxel Dörfler break; 7531fc4cb1fSAxel Dörfler } 7541fc4cb1fSAxel Dörfler } 7551fc4cb1fSAxel Dörfler 7561fc4cb1fSAxel Dörfler item->SetMarked(true); 7571fc4cb1fSAxel Dörfler changed = true; 7581fc4cb1fSAxel Dörfler } 7591fc4cb1fSAxel Dörfler 7601fc4cb1fSAxel Dörfler if (changed) { 7611fc4cb1fSAxel Dörfler // Update selected space 7621fc4cb1fSAxel Dörfler 7631fc4cb1fSAxel Dörfler BMessage* message = item->Message(); 7641fc4cb1fSAxel Dörfler int32 space; 7651fc4cb1fSAxel Dörfler if (message->FindInt32("space", &space) == B_OK) { 7661fc4cb1fSAxel Dörfler fSelected.space = (color_space)space; 7671fc4cb1fSAxel Dörfler _UpdateColorLabel(); 7681fc4cb1fSAxel Dörfler } 7691fc4cb1fSAxel Dörfler } 770a10cf76eSAxel Dörfler } 771a10cf76eSAxel Dörfler 772a10cf76eSAxel Dörfler 7735de171daSAxel Dörfler /*! Enable/disable refresh options according to current mode. */ 774a10cf76eSAxel Dörfler void 7755de171daSAxel Dörfler ScreenWindow::_CheckRefreshMenu() 776a10cf76eSAxel Dörfler { 77729e8a73aSAxel Dörfler float min, max; 77829e8a73aSAxel Dörfler if (fScreenMode.GetRefreshLimits(fSelected, min, max) != B_OK || min == max) 77929e8a73aSAxel Dörfler return; 780a10cf76eSAxel Dörfler 78129e8a73aSAxel Dörfler for (int32 i = fRefreshMenu->CountItems(); i-- > 0;) { 78229e8a73aSAxel Dörfler BMenuItem* item = fRefreshMenu->ItemAt(i); 78329e8a73aSAxel Dörfler BMessage* message = item->Message(); 78429e8a73aSAxel Dörfler float refresh; 78529e8a73aSAxel Dörfler if (message != NULL && message->FindFloat("refresh", &refresh) == B_OK) 78629e8a73aSAxel Dörfler item->SetEnabled(refresh >= min && refresh <= max); 787a10cf76eSAxel Dörfler } 788a10cf76eSAxel Dörfler } 789a10cf76eSAxel Dörfler 790a10cf76eSAxel Dörfler 7915de171daSAxel Dörfler /*! Activate appropriate menu item according to selected refresh rate */ 792a10cf76eSAxel Dörfler void 7935de171daSAxel Dörfler ScreenWindow::_UpdateRefreshControl() 794a10cf76eSAxel Dörfler { 795e96dd823SPulkoMandy if (isnan(fSelected.refresh)) { 796e96dd823SPulkoMandy fRefreshMenu->SetEnabled(false); 797e96dd823SPulkoMandy fOtherRefresh->SetLabel(B_TRANSLATE("Unknown")); 798e96dd823SPulkoMandy fOtherRefresh->SetMarked(true); 799e96dd823SPulkoMandy return; 800e96dd823SPulkoMandy } else { 801e96dd823SPulkoMandy fRefreshMenu->SetEnabled(true); 802e96dd823SPulkoMandy } 803e96dd823SPulkoMandy 8047e44de36SRene Gollent for (int32 i = 0; i < fRefreshMenu->CountItems(); i++) { 8057e44de36SRene Gollent BMenuItem* item = fRefreshMenu->ItemAt(i); 8067e44de36SRene Gollent if (item->Message()->FindFloat("refresh") == fSelected.refresh) { 807a10cf76eSAxel Dörfler item->SetMarked(true); 80826747978SAdrien Destugues // "Other" items only contains a refresh rate when active 809122d4ef7SMurai Takashi if (fOtherRefresh != NULL) 81026747978SAdrien Destugues fOtherRefresh->SetLabel(B_TRANSLATE("Other" B_UTF8_ELLIPSIS)); 811a10cf76eSAxel Dörfler return; 812a10cf76eSAxel Dörfler } 8137e44de36SRene Gollent } 814a10cf76eSAxel Dörfler 815a10cf76eSAxel Dörfler // this is a non-standard refresh rate 8167e44de36SRene Gollent if (fOtherRefresh != NULL) { 817a10cf76eSAxel Dörfler fOtherRefresh->Message()->ReplaceFloat("refresh", fSelected.refresh); 818a10cf76eSAxel Dörfler fOtherRefresh->SetMarked(true); 819a10cf76eSAxel Dörfler 8207e44de36SRene Gollent BString string; 8217e44de36SRene Gollent refresh_rate_to_string(fSelected.refresh, string); 822a10cf76eSAxel Dörfler fRefreshMenu->Superitem()->SetLabel(string.String()); 823a10cf76eSAxel Dörfler 824c9e8f97aSAdrien Destugues string.Append(B_TRANSLATE("/other" B_UTF8_ELLIPSIS)); 825a10cf76eSAxel Dörfler fOtherRefresh->SetLabel(string.String()); 826a10cf76eSAxel Dörfler } 8277e44de36SRene Gollent } 828a10cf76eSAxel Dörfler 829a10cf76eSAxel Dörfler 830a10cf76eSAxel Dörfler void 8315de171daSAxel Dörfler ScreenWindow::_UpdateMonitorView() 832a10cf76eSAxel Dörfler { 833a10cf76eSAxel Dörfler BMessage updateMessage(UPDATE_DESKTOP_MSG); 834a10cf76eSAxel Dörfler updateMessage.AddInt32("width", fSelected.width); 835a10cf76eSAxel Dörfler updateMessage.AddInt32("height", fSelected.height); 836a10cf76eSAxel Dörfler 837a10cf76eSAxel Dörfler PostMessage(&updateMessage, fMonitorView); 838a10cf76eSAxel Dörfler } 839a10cf76eSAxel Dörfler 840a10cf76eSAxel Dörfler 841a10cf76eSAxel Dörfler void 8425de171daSAxel Dörfler ScreenWindow::_UpdateControls() 843a10cf76eSAxel Dörfler { 844b21d610eSAxel Dörfler _UpdateWorkspaceButtons(); 845b21d610eSAxel Dörfler 846a10cf76eSAxel Dörfler BMenuItem* item = fSwapDisplaysMenu->ItemAt((int32)fSelected.swap_displays); 847c33a865cSJohn Scipione if (item != NULL && !item->IsMarked()) 848a10cf76eSAxel Dörfler item->SetMarked(true); 849a10cf76eSAxel Dörfler 850a10cf76eSAxel Dörfler item = fUseLaptopPanelMenu->ItemAt((int32)fSelected.use_laptop_panel); 851c33a865cSJohn Scipione if (item != NULL && !item->IsMarked()) 852a10cf76eSAxel Dörfler item->SetMarked(true); 853a10cf76eSAxel Dörfler 854a10cf76eSAxel Dörfler for (int32 i = 0; i < fTVStandardMenu->CountItems(); i++) { 855a10cf76eSAxel Dörfler item = fTVStandardMenu->ItemAt(i); 856a10cf76eSAxel Dörfler 857a10cf76eSAxel Dörfler uint32 tvStandard; 858a10cf76eSAxel Dörfler item->Message()->FindInt32("tv_standard", (int32 *)&tvStandard); 859a10cf76eSAxel Dörfler if (tvStandard == fSelected.tv_standard) { 860a10cf76eSAxel Dörfler if (!item->IsMarked()) 861a10cf76eSAxel Dörfler item->SetMarked(true); 862a10cf76eSAxel Dörfler break; 863a10cf76eSAxel Dörfler } 864a10cf76eSAxel Dörfler } 865a10cf76eSAxel Dörfler 8665de171daSAxel Dörfler _CheckResolutionMenu(); 8675de171daSAxel Dörfler _CheckColorMenu(); 8685de171daSAxel Dörfler _CheckRefreshMenu(); 869a10cf76eSAxel Dörfler 870a10cf76eSAxel Dörfler BString string; 871a10cf76eSAxel Dörfler resolution_to_string(fSelected, string); 872a10cf76eSAxel Dörfler item = fResolutionMenu->FindItem(string.String()); 873a10cf76eSAxel Dörfler 874a10cf76eSAxel Dörfler if (item != NULL) { 875a10cf76eSAxel Dörfler if (!item->IsMarked()) 876a10cf76eSAxel Dörfler item->SetMarked(true); 877a10cf76eSAxel Dörfler } else { 878a10cf76eSAxel Dörfler // this is bad luck - if mode has been set via screen references, 879a10cf76eSAxel Dörfler // this case cannot occur; there are three possible solutions: 880a10cf76eSAxel Dörfler // 1. add a new resolution to list 881a10cf76eSAxel Dörfler // - we had to remove it as soon as a "valid" one is selected 882a10cf76eSAxel Dörfler // - we don't know which frequencies/bit depths are supported 883a10cf76eSAxel Dörfler // - as long as we haven't the GMT formula to create 884a10cf76eSAxel Dörfler // parameters for any resolution given, we cannot 885a10cf76eSAxel Dörfler // really set current mode - it's just not in the list 886a10cf76eSAxel Dörfler // 2. choose nearest resolution 887a10cf76eSAxel Dörfler // - probably a good idea, but implies coding and testing 888a10cf76eSAxel Dörfler // 3. choose lowest resolution 889a10cf76eSAxel Dörfler // - do you really think we are so lazy? yes, we are 890a10cf76eSAxel Dörfler item = fResolutionMenu->ItemAt(0); 891a10cf76eSAxel Dörfler if (item) 892a10cf76eSAxel Dörfler item->SetMarked(true); 893a10cf76eSAxel Dörfler 894a10cf76eSAxel Dörfler // okay - at least we set menu label to active resolution 895a10cf76eSAxel Dörfler fResolutionMenu->Superitem()->SetLabel(string.String()); 896a10cf76eSAxel Dörfler } 897a10cf76eSAxel Dörfler 898a10cf76eSAxel Dörfler // mark active combine mode 899a10cf76eSAxel Dörfler for (int32 i = 0; i < kCombineModeCount; i++) { 900a10cf76eSAxel Dörfler if (kCombineModes[i].mode == fSelected.combine) { 901a10cf76eSAxel Dörfler item = fCombineMenu->ItemAt(i); 902c33a865cSJohn Scipione if (item != NULL && !item->IsMarked()) 903a10cf76eSAxel Dörfler item->SetMarked(true); 904a10cf76eSAxel Dörfler break; 905a10cf76eSAxel Dörfler } 906a10cf76eSAxel Dörfler } 907a10cf76eSAxel Dörfler 908a10cf76eSAxel Dörfler item = fColorsMenu->ItemAt(0); 909a10cf76eSAxel Dörfler 9101fc4cb1fSAxel Dörfler for (int32 i = 0, index = 0; i < kColorSpaceCount; i++) { 9111fc4cb1fSAxel Dörfler if ((fSupportedColorSpaces & (1 << i)) == 0) 9121fc4cb1fSAxel Dörfler continue; 9131fc4cb1fSAxel Dörfler 9141fc4cb1fSAxel Dörfler if (kColorSpaces[i].space == fSelected.space) { 9151fc4cb1fSAxel Dörfler item = fColorsMenu->ItemAt(index); 916a10cf76eSAxel Dörfler break; 917a10cf76eSAxel Dörfler } 9181fc4cb1fSAxel Dörfler 9191fc4cb1fSAxel Dörfler index++; 920a10cf76eSAxel Dörfler } 921a10cf76eSAxel Dörfler 922c33a865cSJohn Scipione if (item != NULL && !item->IsMarked()) 923a10cf76eSAxel Dörfler item->SetMarked(true); 924a10cf76eSAxel Dörfler 9251fc4cb1fSAxel Dörfler _UpdateColorLabel(); 9265de171daSAxel Dörfler _UpdateMonitorView(); 9275de171daSAxel Dörfler _UpdateRefreshControl(); 928a10cf76eSAxel Dörfler 9295de171daSAxel Dörfler _CheckApplyEnabled(); 930a10cf76eSAxel Dörfler } 931a10cf76eSAxel Dörfler 932a10cf76eSAxel Dörfler 93312580984SAxel Dörfler /*! Reflect active mode in chosen settings */ 934a10cf76eSAxel Dörfler void 9355de171daSAxel Dörfler ScreenWindow::_UpdateActiveMode() 936a10cf76eSAxel Dörfler { 937c491b5adSJohn Scipione _UpdateActiveMode(current_workspace()); 938c491b5adSJohn Scipione } 939c491b5adSJohn Scipione 940c491b5adSJohn Scipione 941c491b5adSJohn Scipione void 942c491b5adSJohn Scipione ScreenWindow::_UpdateActiveMode(int32 workspace) 943c491b5adSJohn Scipione { 94412580984SAxel Dörfler // Usually, this function gets called after a mode 945a10cf76eSAxel Dörfler // has been set manually; still, as the graphics driver 946a10cf76eSAxel Dörfler // is free to fiddle with mode passed, we better ask 947a10cf76eSAxel Dörfler // what kind of mode we actually got 948c491b5adSJohn Scipione if (fScreenMode.Get(fActive, workspace) == B_OK) { 949a10cf76eSAxel Dörfler fSelected = fActive; 950a10cf76eSAxel Dörfler 95112966d04SAxel Dörfler _UpdateMonitor(); 952c491b5adSJohn Scipione _BuildSupportedColorSpaces(); 9535de171daSAxel Dörfler _UpdateControls(); 954a10cf76eSAxel Dörfler } 955c491b5adSJohn Scipione } 956a10cf76eSAxel Dörfler 957a10cf76eSAxel Dörfler 958a10cf76eSAxel Dörfler void 959b21d610eSAxel Dörfler ScreenWindow::_UpdateWorkspaceButtons() 960b21d610eSAxel Dörfler { 961b21d610eSAxel Dörfler uint32 columns; 962b21d610eSAxel Dörfler uint32 rows; 963b21d610eSAxel Dörfler BPrivate::get_workspaces_layout(&columns, &rows); 964b21d610eSAxel Dörfler 965a3fa81bdSJohn Scipione // Set the max values enabling/disabling the up/down arrows 966b21d610eSAxel Dörfler 967a3fa81bdSJohn Scipione if (rows == 1) 968a3fa81bdSJohn Scipione fColumnsControl->SetMaxValue(32); 969a3fa81bdSJohn Scipione else if (rows == 2) 970a3fa81bdSJohn Scipione fColumnsControl->SetMaxValue(16); 971a3fa81bdSJohn Scipione else if (rows <= 4) 972a3fa81bdSJohn Scipione fColumnsControl->SetMaxValue(8); 973a3fa81bdSJohn Scipione else if (rows <= 8) 974a3fa81bdSJohn Scipione fColumnsControl->SetMaxValue(4); 975a3fa81bdSJohn Scipione else if (rows <= 16) 976a3fa81bdSJohn Scipione fColumnsControl->SetMaxValue(2); 977a3fa81bdSJohn Scipione else if (rows <= 32) 978a3fa81bdSJohn Scipione fColumnsControl->SetMaxValue(1); 979b21d610eSAxel Dörfler 980a3fa81bdSJohn Scipione if (columns == 1) 981a3fa81bdSJohn Scipione fRowsControl->SetMaxValue(32); 982a3fa81bdSJohn Scipione else if (columns == 2) 983a3fa81bdSJohn Scipione fRowsControl->SetMaxValue(16); 984a3fa81bdSJohn Scipione else if (columns <= 4) 985a3fa81bdSJohn Scipione fRowsControl->SetMaxValue(8); 986a3fa81bdSJohn Scipione else if (columns <= 8) 987a3fa81bdSJohn Scipione fRowsControl->SetMaxValue(4); 988a3fa81bdSJohn Scipione else if (columns <= 16) 989a3fa81bdSJohn Scipione fRowsControl->SetMaxValue(2); 990a3fa81bdSJohn Scipione else if (columns <= 32) 991a3fa81bdSJohn Scipione fRowsControl->SetMaxValue(1); 992b21d610eSAxel Dörfler } 993b21d610eSAxel Dörfler 994b21d610eSAxel Dörfler 995b21d610eSAxel Dörfler void 996a10cf76eSAxel Dörfler ScreenWindow::ScreenChanged(BRect frame, color_space mode) 997a10cf76eSAxel Dörfler { 998a10cf76eSAxel Dörfler // move window on screen, if necessary 999a10cf76eSAxel Dörfler if (frame.right <= Frame().right 1000a10cf76eSAxel Dörfler && frame.bottom <= Frame().bottom) { 1001a10cf76eSAxel Dörfler MoveTo((frame.Width() - Frame().Width()) / 2, 1002a10cf76eSAxel Dörfler (frame.Height() - Frame().Height()) / 2); 1003a10cf76eSAxel Dörfler } 1004a10cf76eSAxel Dörfler } 1005a10cf76eSAxel Dörfler 1006a10cf76eSAxel Dörfler 1007a10cf76eSAxel Dörfler void 1008a10cf76eSAxel Dörfler ScreenWindow::WorkspaceActivated(int32 workspace, bool state) 1009a10cf76eSAxel Dörfler { 1010c491b5adSJohn Scipione if (fScreenMode.GetOriginalMode(fOriginal, workspace) == B_OK) { 1011c491b5adSJohn Scipione _UpdateActiveMode(workspace); 1012a10cf76eSAxel Dörfler 10136edaa0f6SStefano Ceccherini BMessage message(UPDATE_DESKTOP_COLOR_MSG); 10146edaa0f6SStefano Ceccherini PostMessage(&message, fMonitorView); 1015a10cf76eSAxel Dörfler } 1016c491b5adSJohn Scipione } 1017a10cf76eSAxel Dörfler 1018a10cf76eSAxel Dörfler 1019a10cf76eSAxel Dörfler void 1020a10cf76eSAxel Dörfler ScreenWindow::MessageReceived(BMessage* message) 1021a10cf76eSAxel Dörfler { 1022a10cf76eSAxel Dörfler switch (message->what) { 1023a10cf76eSAxel Dörfler case WORKSPACE_CHECK_MSG: 10245de171daSAxel Dörfler _CheckApplyEnabled(); 1025a10cf76eSAxel Dörfler break; 1026a10cf76eSAxel Dörfler 1027b21d610eSAxel Dörfler case kMsgWorkspaceColumnsChanged: 1028b21d610eSAxel Dörfler { 1029a3fa81bdSJohn Scipione uint32 newColumns = (uint32)fColumnsControl->Value(); 1030b21d610eSAxel Dörfler 1031b21d610eSAxel Dörfler uint32 rows; 1032b21d610eSAxel Dörfler BPrivate::get_workspaces_layout(NULL, &rows); 1033b21d610eSAxel Dörfler BPrivate::set_workspaces_layout(newColumns, rows); 1034b21d610eSAxel Dörfler 1035b21d610eSAxel Dörfler _UpdateWorkspaceButtons(); 1036a3fa81bdSJohn Scipione fRowsControl->SetValue(rows); 1037a3fa81bdSJohn Scipione // enables/disables up/down arrows 1038b21d610eSAxel Dörfler _CheckApplyEnabled(); 1039a3fa81bdSJohn Scipione 1040b21d610eSAxel Dörfler break; 1041b21d610eSAxel Dörfler } 1042b21d610eSAxel Dörfler 1043b21d610eSAxel Dörfler case kMsgWorkspaceRowsChanged: 1044b21d610eSAxel Dörfler { 1045a3fa81bdSJohn Scipione uint32 newRows = (uint32)fRowsControl->Value(); 1046b21d610eSAxel Dörfler 1047b21d610eSAxel Dörfler uint32 columns; 1048b21d610eSAxel Dörfler BPrivate::get_workspaces_layout(&columns, NULL); 1049b21d610eSAxel Dörfler BPrivate::set_workspaces_layout(columns, newRows); 1050b21d610eSAxel Dörfler 1051b21d610eSAxel Dörfler _UpdateWorkspaceButtons(); 1052a3fa81bdSJohn Scipione fColumnsControl->SetValue(columns); 1053a3fa81bdSJohn Scipione // enables/disables up/down arrows 1054b21d610eSAxel Dörfler _CheckApplyEnabled(); 1055a10cf76eSAxel Dörfler break; 1056a10cf76eSAxel Dörfler } 1057a10cf76eSAxel Dörfler 1058a10cf76eSAxel Dörfler case POP_RESOLUTION_MSG: 1059a10cf76eSAxel Dörfler { 1060a10cf76eSAxel Dörfler message->FindInt32("width", &fSelected.width); 1061a10cf76eSAxel Dörfler message->FindInt32("height", &fSelected.height); 1062a10cf76eSAxel Dörfler 10635de171daSAxel Dörfler _CheckColorMenu(); 10645de171daSAxel Dörfler _CheckRefreshMenu(); 1065a10cf76eSAxel Dörfler 10665de171daSAxel Dörfler _UpdateMonitorView(); 10675de171daSAxel Dörfler _UpdateRefreshControl(); 1068a10cf76eSAxel Dörfler 10695de171daSAxel Dörfler _CheckApplyEnabled(); 1070a10cf76eSAxel Dörfler break; 1071a10cf76eSAxel Dörfler } 1072a10cf76eSAxel Dörfler 1073a10cf76eSAxel Dörfler case POP_COLORS_MSG: 1074a10cf76eSAxel Dörfler { 10751fc4cb1fSAxel Dörfler int32 space; 10761fc4cb1fSAxel Dörfler if (message->FindInt32("space", &space) != B_OK) 10771fc4cb1fSAxel Dörfler break; 1078a10cf76eSAxel Dörfler 10791fc4cb1fSAxel Dörfler int32 index; 10801fc4cb1fSAxel Dörfler if (message->FindInt32("index", &index) == B_OK 10811fc4cb1fSAxel Dörfler && fColorsMenu->ItemAt(index) != NULL) 10821fc4cb1fSAxel Dörfler fUserSelectedColorSpace = fColorsMenu->ItemAt(index); 10831fc4cb1fSAxel Dörfler 10841fc4cb1fSAxel Dörfler fSelected.space = (color_space)space; 10851fc4cb1fSAxel Dörfler _UpdateColorLabel(); 1086a10cf76eSAxel Dörfler 10875de171daSAxel Dörfler _CheckApplyEnabled(); 1088a10cf76eSAxel Dörfler break; 1089a10cf76eSAxel Dörfler } 1090a10cf76eSAxel Dörfler 1091a10cf76eSAxel Dörfler case POP_REFRESH_MSG: 1092a40498e2SWaldemar Kornewald { 1093a10cf76eSAxel Dörfler message->FindFloat("refresh", &fSelected.refresh); 1094c9e8f97aSAdrien Destugues fOtherRefresh->SetLabel(B_TRANSLATE("Other" B_UTF8_ELLIPSIS)); 10951fc4cb1fSAxel Dörfler // revert "Other…" label - it might have a refresh rate prefix 1096a10cf76eSAxel Dörfler 10975de171daSAxel Dörfler _CheckApplyEnabled(); 1098a10cf76eSAxel Dörfler break; 1099a40498e2SWaldemar Kornewald } 1100a10cf76eSAxel Dörfler 1101a10cf76eSAxel Dörfler case POP_OTHER_REFRESH_MSG: 1102a10cf76eSAxel Dörfler { 110329e8a73aSAxel Dörfler // make sure menu shows something useful 11045de171daSAxel Dörfler _UpdateRefreshControl(); 1105a10cf76eSAxel Dörfler 110629e8a73aSAxel Dörfler float min = 0, max = 999; 110729e8a73aSAxel Dörfler fScreenMode.GetRefreshLimits(fSelected, min, max); 110829e8a73aSAxel Dörfler if (min < gMinRefresh) 110929e8a73aSAxel Dörfler min = gMinRefresh; 111029e8a73aSAxel Dörfler if (max > gMaxRefresh) 111129e8a73aSAxel Dörfler max = gMaxRefresh; 111229e8a73aSAxel Dörfler 111370a2b1b5SAxel Dörfler monitor_info info; 111470a2b1b5SAxel Dörfler if (fScreenMode.GetMonitorInfo(info) == B_OK) { 111570a2b1b5SAxel Dörfler min = max_c(info.min_vertical_frequency, min); 111670a2b1b5SAxel Dörfler max = min_c(info.max_vertical_frequency, max); 111770a2b1b5SAxel Dörfler } 111870a2b1b5SAxel Dörfler 1119c5d10f7aSAxel Dörfler RefreshWindow *fRefreshWindow = new RefreshWindow( 112070a2b1b5SAxel Dörfler fRefreshField->ConvertToScreen(B_ORIGIN), fSelected.refresh, 112170a2b1b5SAxel Dörfler min, max); 1122a10cf76eSAxel Dörfler fRefreshWindow->Show(); 1123a10cf76eSAxel Dörfler break; 1124a10cf76eSAxel Dörfler } 1125a10cf76eSAxel Dörfler 1126a10cf76eSAxel Dörfler case SET_CUSTOM_REFRESH_MSG: 1127a10cf76eSAxel Dörfler { 1128a10cf76eSAxel Dörfler // user pressed "done" in "Other…" refresh dialog; 1129a10cf76eSAxel Dörfler // select the refresh rate chosen 1130a10cf76eSAxel Dörfler message->FindFloat("refresh", &fSelected.refresh); 1131a10cf76eSAxel Dörfler 11325de171daSAxel Dörfler _UpdateRefreshControl(); 11335de171daSAxel Dörfler _CheckApplyEnabled(); 1134a10cf76eSAxel Dörfler break; 1135a10cf76eSAxel Dörfler } 1136a10cf76eSAxel Dörfler 1137a10cf76eSAxel Dörfler case POP_COMBINE_DISPLAYS_MSG: 1138a10cf76eSAxel Dörfler { 1139a10cf76eSAxel Dörfler // new combine mode has bee chosen 1140a10cf76eSAxel Dörfler int32 mode; 1141a10cf76eSAxel Dörfler if (message->FindInt32("mode", &mode) == B_OK) 1142a10cf76eSAxel Dörfler fSelected.combine = (combine_mode)mode; 1143a10cf76eSAxel Dörfler 11445de171daSAxel Dörfler _CheckResolutionMenu(); 11455de171daSAxel Dörfler _CheckApplyEnabled(); 1146a10cf76eSAxel Dörfler break; 1147a10cf76eSAxel Dörfler } 1148a10cf76eSAxel Dörfler 1149a10cf76eSAxel Dörfler case POP_SWAP_DISPLAYS_MSG: 1150a10cf76eSAxel Dörfler message->FindBool("swap", &fSelected.swap_displays); 11515de171daSAxel Dörfler _CheckApplyEnabled(); 1152a10cf76eSAxel Dörfler break; 1153a10cf76eSAxel Dörfler 1154a10cf76eSAxel Dörfler case POP_USE_LAPTOP_PANEL_MSG: 1155a10cf76eSAxel Dörfler message->FindBool("use", &fSelected.use_laptop_panel); 11565de171daSAxel Dörfler _CheckApplyEnabled(); 1157a10cf76eSAxel Dörfler break; 1158a10cf76eSAxel Dörfler 1159a10cf76eSAxel Dörfler case POP_TV_STANDARD_MSG: 1160a10cf76eSAxel Dörfler message->FindInt32("tv_standard", (int32 *)&fSelected.tv_standard); 11615de171daSAxel Dörfler _CheckApplyEnabled(); 1162a10cf76eSAxel Dörfler break; 1163a10cf76eSAxel Dörfler 1164df3f5bacSStephan Aßmus case BUTTON_LAUNCH_BACKGROUNDS_MSG: 11656f095d6aSRyan Leavengood if (be_roster->Launch(kBackgroundsSignature) == B_ALREADY_RUNNING) { 11666f095d6aSRyan Leavengood app_info info; 11676f095d6aSRyan Leavengood be_roster->GetAppInfo(kBackgroundsSignature, &info); 11686f095d6aSRyan Leavengood be_roster->ActivateApp(info.team); 11696f095d6aSRyan Leavengood } 1170df3f5bacSStephan Aßmus break; 1171df3f5bacSStephan Aßmus 1172a10cf76eSAxel Dörfler case BUTTON_DEFAULTS_MSG: 1173a10cf76eSAxel Dörfler { 11744be51fe3SWaldemar Kornewald // TODO: get preferred settings of screen 1175a10cf76eSAxel Dörfler fSelected.width = 640; 1176a10cf76eSAxel Dörfler fSelected.height = 480; 1177a10cf76eSAxel Dörfler fSelected.space = B_CMAP8; 1178a10cf76eSAxel Dörfler fSelected.refresh = 60.0; 1179a10cf76eSAxel Dörfler fSelected.combine = kCombineDisable; 1180a10cf76eSAxel Dörfler fSelected.swap_displays = false; 1181a10cf76eSAxel Dörfler fSelected.use_laptop_panel = false; 1182a10cf76eSAxel Dörfler fSelected.tv_standard = 0; 1183a10cf76eSAxel Dörfler 1184b21d610eSAxel Dörfler // TODO: workspace defaults 1185abc649b8SWaldemar Kornewald 11865de171daSAxel Dörfler _UpdateControls(); 1187a10cf76eSAxel Dörfler break; 1188a10cf76eSAxel Dörfler } 1189a10cf76eSAxel Dörfler 119010e9b12fSWaldemar Kornewald case BUTTON_UNDO_MSG: 119161c5c89bSAxel Dörfler fUndoScreenMode.Revert(); 11925de171daSAxel Dörfler _UpdateActiveMode(); 1193abc649b8SWaldemar Kornewald break; 1194abc649b8SWaldemar Kornewald 1195abc649b8SWaldemar Kornewald case BUTTON_REVERT_MSG: 1196abc649b8SWaldemar Kornewald { 1197abc649b8SWaldemar Kornewald fModified = false; 1198199893c3SAxel Dörfler fBootWorkspaceApplied = false; 1199abc649b8SWaldemar Kornewald 1200b21d610eSAxel Dörfler // ScreenMode::Revert() assumes that we first set the correct 1201b21d610eSAxel Dörfler // number of workspaces 1202b21d610eSAxel Dörfler 1203b21d610eSAxel Dörfler BPrivate::set_workspaces_layout(fOriginalWorkspacesColumns, 1204b21d610eSAxel Dörfler fOriginalWorkspacesRows); 1205b21d610eSAxel Dörfler _UpdateWorkspaceButtons(); 1206b21d610eSAxel Dörfler 1207a10cf76eSAxel Dörfler fScreenMode.Revert(); 12083a2b67b5SAdrien Destugues 12093a2b67b5SAdrien Destugues BScreen screen(this); 12103a2b67b5SAdrien Destugues screen.SetBrightness(fOriginalBrightness); 12113a2b67b5SAdrien Destugues fBrightnessSlider->SetValue(fOriginalBrightness * 255); 12121f2666fdSJadedTuna 12131f2666fdSJadedTuna _UpdateActiveMode(); 1214a10cf76eSAxel Dörfler break; 1215abc649b8SWaldemar Kornewald } 1216a10cf76eSAxel Dörfler 1217a10cf76eSAxel Dörfler case BUTTON_APPLY_MSG: 12185de171daSAxel Dörfler _Apply(); 1219a10cf76eSAxel Dörfler break; 1220a10cf76eSAxel Dörfler 1221abc649b8SWaldemar Kornewald case MAKE_INITIAL_MSG: 1222abc649b8SWaldemar Kornewald // user pressed "keep" in confirmation dialog 1223abc649b8SWaldemar Kornewald fModified = true; 12245de171daSAxel Dörfler _UpdateActiveMode(); 1225a10cf76eSAxel Dörfler break; 1226a10cf76eSAxel Dörfler 1227b8a61399SBrian Hill case UPDATE_DESKTOP_COLOR_MSG: 1228b8a61399SBrian Hill PostMessage(message, fMonitorView); 1229b8a61399SBrian Hill break; 1230b8a61399SBrian Hill 12313a2b67b5SAdrien Destugues case SLIDER_BRIGHTNESS_MSG: 12323a2b67b5SAdrien Destugues { 12333a2b67b5SAdrien Destugues BScreen screen(this); 12343a2b67b5SAdrien Destugues screen.SetBrightness(message->FindInt32("be:value") / 255.f); 12353a2b67b5SAdrien Destugues _CheckApplyEnabled(); 12363a2b67b5SAdrien Destugues break; 12373a2b67b5SAdrien Destugues } 12383a2b67b5SAdrien Destugues 1239a10cf76eSAxel Dörfler default: 1240a10cf76eSAxel Dörfler BWindow::MessageReceived(message); 1241a10cf76eSAxel Dörfler } 1242a10cf76eSAxel Dörfler } 1243a10cf76eSAxel Dörfler 1244a10cf76eSAxel Dörfler 124512580984SAxel Dörfler status_t 124612580984SAxel Dörfler ScreenWindow::_WriteVesaModeFile(const screen_mode& mode) const 124712580984SAxel Dörfler { 124812580984SAxel Dörfler BPath path; 124912580984SAxel Dörfler status_t status = find_directory(B_USER_SETTINGS_DIRECTORY, &path, true); 125012580984SAxel Dörfler if (status < B_OK) 125112580984SAxel Dörfler return status; 125212580984SAxel Dörfler 125312580984SAxel Dörfler path.Append("kernel/drivers"); 125412580984SAxel Dörfler status = create_directory(path.Path(), 0755); 125512580984SAxel Dörfler if (status < B_OK) 125612580984SAxel Dörfler return status; 125712580984SAxel Dörfler 125812580984SAxel Dörfler path.Append("vesa"); 125912580984SAxel Dörfler BFile file; 126012580984SAxel Dörfler status = file.SetTo(path.Path(), B_CREATE_FILE | B_WRITE_ONLY | B_ERASE_FILE); 126112580984SAxel Dörfler if (status < B_OK) 126212580984SAxel Dörfler return status; 126312580984SAxel Dörfler 126412580984SAxel Dörfler char buffer[256]; 12655084d0d4SAlex Smith snprintf(buffer, sizeof(buffer), "mode %" B_PRId32 " %" B_PRId32 " %" 12665084d0d4SAlex Smith B_PRId32 "\n", mode.width, mode.height, mode.BitsPerPixel()); 126712580984SAxel Dörfler 126812580984SAxel Dörfler ssize_t bytesWritten = file.Write(buffer, strlen(buffer)); 126912580984SAxel Dörfler if (bytesWritten < B_OK) 127012580984SAxel Dörfler return bytesWritten; 127112580984SAxel Dörfler 127212580984SAxel Dörfler return B_OK; 127312580984SAxel Dörfler } 127412580984SAxel Dörfler 127512580984SAxel Dörfler 1276a10cf76eSAxel Dörfler void 12771fc4cb1fSAxel Dörfler ScreenWindow::_BuildSupportedColorSpaces() 12781fc4cb1fSAxel Dörfler { 12791fc4cb1fSAxel Dörfler fSupportedColorSpaces = 0; 12801fc4cb1fSAxel Dörfler 12811fc4cb1fSAxel Dörfler for (int32 i = 0; i < kColorSpaceCount; i++) { 12821fc4cb1fSAxel Dörfler for (int32 j = 0; j < fScreenMode.CountModes(); j++) { 12831fc4cb1fSAxel Dörfler if (fScreenMode.ModeAt(j).space == kColorSpaces[i].space) { 12841fc4cb1fSAxel Dörfler fSupportedColorSpaces |= 1 << i; 12851fc4cb1fSAxel Dörfler break; 12861fc4cb1fSAxel Dörfler } 12871fc4cb1fSAxel Dörfler } 12881fc4cb1fSAxel Dörfler } 12891fc4cb1fSAxel Dörfler } 12901fc4cb1fSAxel Dörfler 12911fc4cb1fSAxel Dörfler 12921fc4cb1fSAxel Dörfler void 12935de171daSAxel Dörfler ScreenWindow::_CheckApplyEnabled() 1294a10cf76eSAxel Dörfler { 129595ef5044SJanus bool applyEnabled = true; 129695ef5044SJanus 129795ef5044SJanus if (fSelected == fActive) { 129895ef5044SJanus applyEnabled = false; 129995ef5044SJanus if (fAllWorkspacesItem->IsMarked()) { 130095ef5044SJanus screen_mode screenMode; 130195ef5044SJanus const int32 workspaceCount = count_workspaces(); 130295ef5044SJanus for (int32 i = 0; i < workspaceCount; i++) { 130395ef5044SJanus fScreenMode.Get(screenMode, i); 130495ef5044SJanus if (screenMode != fSelected) { 130595ef5044SJanus applyEnabled = true; 130695ef5044SJanus break; 130795ef5044SJanus } 130895ef5044SJanus } 130995ef5044SJanus } 131095ef5044SJanus } 131195ef5044SJanus 131295ef5044SJanus fApplyButton->SetEnabled(applyEnabled); 1313b21d610eSAxel Dörfler 1314b21d610eSAxel Dörfler uint32 columns; 1315b21d610eSAxel Dörfler uint32 rows; 1316b21d610eSAxel Dörfler BPrivate::get_workspaces_layout(&columns, &rows); 1317b21d610eSAxel Dörfler 13183a2b67b5SAdrien Destugues BScreen screen(this); 13193a2b67b5SAdrien Destugues float brightness = -1; 13203a2b67b5SAdrien Destugues screen.GetBrightness(&brightness); 13213a2b67b5SAdrien Destugues 1322b21d610eSAxel Dörfler fRevertButton->SetEnabled(columns != fOriginalWorkspacesColumns 1323b21d610eSAxel Dörfler || rows != fOriginalWorkspacesRows 13243a2b67b5SAdrien Destugues || brightness != fOriginalBrightness 13255de171daSAxel Dörfler || fSelected != fOriginal); 1326a10cf76eSAxel Dörfler } 1327a10cf76eSAxel Dörfler 1328a10cf76eSAxel Dörfler 1329a10cf76eSAxel Dörfler void 13305de171daSAxel Dörfler ScreenWindow::_UpdateOriginal() 1331abc649b8SWaldemar Kornewald { 1332b21d610eSAxel Dörfler BPrivate::get_workspaces_layout(&fOriginalWorkspacesColumns, 1333b21d610eSAxel Dörfler &fOriginalWorkspacesRows); 1334b21d610eSAxel Dörfler 1335abc649b8SWaldemar Kornewald fScreenMode.Get(fOriginal); 1336abc649b8SWaldemar Kornewald fScreenMode.UpdateOriginalModes(); 1337abc649b8SWaldemar Kornewald } 1338abc649b8SWaldemar Kornewald 1339abc649b8SWaldemar Kornewald 1340abc649b8SWaldemar Kornewald void 134112966d04SAxel Dörfler ScreenWindow::_UpdateMonitor() 134212966d04SAxel Dörfler { 134312966d04SAxel Dörfler monitor_info info; 134412966d04SAxel Dörfler float diagonalInches; 134512966d04SAxel Dörfler status_t status = fScreenMode.GetMonitorInfo(info, &diagonalInches); 134655030977SAxel Dörfler if (status == B_OK) { 13471a8af605SAxel Dörfler char text[512]; 134866ab1666SAxel Dörfler snprintf(text, sizeof(text), "%s%s%s %g\"", info.vendor, 134966ab1666SAxel Dörfler info.name[0] ? " " : "", info.name, diagonalInches); 135012966d04SAxel Dörfler 1351ef046e3bSJohn Scipione fScreenBox->SetLabel(text); 135255030977SAxel Dörfler } else { 1353ef046e3bSJohn Scipione fScreenBox->SetLabel(B_TRANSLATE("Display info")); 135455030977SAxel Dörfler } 1355af8f9c31SAxel Dörfler 13568b46ee25SAdrien Destugues // Add info about the graphics device 13578b46ee25SAdrien Destugues 13588b46ee25SAdrien Destugues accelerant_device_info deviceInfo; 13598b46ee25SAdrien Destugues 13608b46ee25SAdrien Destugues if (fScreenMode.GetDeviceInfo(deviceInfo) == B_OK) { 13618b46ee25SAdrien Destugues BString deviceString; 13628b46ee25SAdrien Destugues 13638b46ee25SAdrien Destugues if (deviceInfo.name[0] && deviceInfo.chipset[0]) { 13648b46ee25SAdrien Destugues deviceString.SetToFormat("%s (%s)", deviceInfo.name, 13658b46ee25SAdrien Destugues deviceInfo.chipset); 13668b46ee25SAdrien Destugues } else if (deviceInfo.name[0] || deviceInfo.chipset[0]) { 13678b46ee25SAdrien Destugues deviceString 13688b46ee25SAdrien Destugues = deviceInfo.name[0] ? deviceInfo.name : deviceInfo.chipset; 13698b46ee25SAdrien Destugues } 13708b46ee25SAdrien Destugues 13718b46ee25SAdrien Destugues fDeviceInfo->SetText(deviceString); 13728b46ee25SAdrien Destugues } 13738b46ee25SAdrien Destugues 13748b46ee25SAdrien Destugues 137555030977SAxel Dörfler char text[512]; 13761a8af605SAxel Dörfler size_t length = 0; 13771a8af605SAxel Dörfler text[0] = 0; 13781a8af605SAxel Dörfler 137955030977SAxel Dörfler if (status == B_OK) { 1380af8f9c31SAxel Dörfler if (info.min_horizontal_frequency != 0 1381af8f9c31SAxel Dörfler && info.min_vertical_frequency != 0 1382af8f9c31SAxel Dörfler && info.max_pixel_clock != 0) { 13831a8af605SAxel Dörfler length = snprintf(text, sizeof(text), 1384c9e8f97aSAdrien Destugues B_TRANSLATE("Horizonal frequency:\t%lu - %lu kHz\n" 13859c1a9b92SAdrien Destugues "Vertical frequency:\t%lu - %lu Hz\n\n" 1386c9e8f97aSAdrien Destugues "Maximum pixel clock:\t%g MHz"), 1387*7eab6b48SPulkoMandy (long unsigned)info.min_horizontal_frequency, 1388*7eab6b48SPulkoMandy (long unsigned)info.max_horizontal_frequency, 1389*7eab6b48SPulkoMandy (long unsigned)info.min_vertical_frequency, 1390*7eab6b48SPulkoMandy (long unsigned)info.max_vertical_frequency, 13911a8af605SAxel Dörfler info.max_pixel_clock / 1000.0); 1392af8f9c31SAxel Dörfler } 13931a8af605SAxel Dörfler if (info.serial_number[0] && length < sizeof(text)) { 1394e96dd823SPulkoMandy if (length > 0) { 1395e96dd823SPulkoMandy text[length++] = '\n'; 1396e96dd823SPulkoMandy text[length++] = '\n'; 1397e96dd823SPulkoMandy text[length] = '\0'; 1398e96dd823SPulkoMandy } 13991a8af605SAxel Dörfler length += snprintf(text + length, sizeof(text) - length, 1400e96dd823SPulkoMandy B_TRANSLATE("Serial no.: %s"), info.serial_number); 14011a8af605SAxel Dörfler if (info.produced.week != 0 && info.produced.year != 0 14021a8af605SAxel Dörfler && length < sizeof(text)) { 14031a8af605SAxel Dörfler length += snprintf(text + length, sizeof(text) - length, 14041a8af605SAxel Dörfler " (%u/%u)", info.produced.week, info.produced.year); 14051a8af605SAxel Dörfler } 14061a8af605SAxel Dörfler } 140755030977SAxel Dörfler } 140861c5c89bSAxel Dörfler 14091a8af605SAxel Dörfler if (text[0]) 14101a8af605SAxel Dörfler fMonitorView->SetToolTip(text); 141112966d04SAxel Dörfler } 141212966d04SAxel Dörfler 141312966d04SAxel Dörfler 141412966d04SAxel Dörfler void 14151fc4cb1fSAxel Dörfler ScreenWindow::_UpdateColorLabel() 14161fc4cb1fSAxel Dörfler { 14171fc4cb1fSAxel Dörfler BString string; 1418551c9f15SSiarzhuk Zharski string << fSelected.BitsPerPixel() << " " << B_TRANSLATE("bits/pixel"); 14191fc4cb1fSAxel Dörfler fColorsMenu->Superitem()->SetLabel(string.String()); 14201fc4cb1fSAxel Dörfler } 14211fc4cb1fSAxel Dörfler 14221fc4cb1fSAxel Dörfler 14231fc4cb1fSAxel Dörfler void 14245de171daSAxel Dörfler ScreenWindow::_Apply() 1425a10cf76eSAxel Dörfler { 1426abc649b8SWaldemar Kornewald // make checkpoint, so we can undo these changes 142761c5c89bSAxel Dörfler fUndoScreenMode.UpdateOriginalModes(); 142861c5c89bSAxel Dörfler 142907184a9eSAxel Dörfler status_t status = fScreenMode.Set(fSelected); 143007184a9eSAxel Dörfler if (status == B_OK) { 1431abc649b8SWaldemar Kornewald // use the mode that has eventually been set and 1432abc649b8SWaldemar Kornewald // thus we know to be working; it can differ from 1433abc649b8SWaldemar Kornewald // the mode selected by user due to hardware limitation 1434abc649b8SWaldemar Kornewald display_mode newMode; 1435abc649b8SWaldemar Kornewald BScreen screen(this); 1436abc649b8SWaldemar Kornewald screen.GetMode(&newMode); 1437abc649b8SWaldemar Kornewald 1438abc649b8SWaldemar Kornewald if (fAllWorkspacesItem->IsMarked()) { 1439abc649b8SWaldemar Kornewald int32 originatingWorkspace = current_workspace(); 144095ef5044SJanus const int32 workspaceCount = count_workspaces(); 144195ef5044SJanus for (int32 i = 0; i < workspaceCount; i++) { 1442abc649b8SWaldemar Kornewald if (i != originatingWorkspace) 1443abc649b8SWaldemar Kornewald screen.SetMode(i, &newMode, true); 1444abc649b8SWaldemar Kornewald } 1445199893c3SAxel Dörfler fBootWorkspaceApplied = true; 1446199893c3SAxel Dörfler } else { 1447199893c3SAxel Dörfler if (current_workspace() == 0) 1448199893c3SAxel Dörfler fBootWorkspaceApplied = true; 1449abc649b8SWaldemar Kornewald } 1450abc649b8SWaldemar Kornewald 1451a10cf76eSAxel Dörfler fActive = fSelected; 1452a10cf76eSAxel Dörfler 1453abc649b8SWaldemar Kornewald // TODO: only show alert when this is an unknown mode 145441f43d56SAugustin Cavalier BAlert* window = new AlertWindow(this); 145541f43d56SAugustin Cavalier window->Go(NULL); 145607184a9eSAxel Dörfler } else { 145707184a9eSAxel Dörfler char message[256]; 145807184a9eSAxel Dörfler snprintf(message, sizeof(message), 1459c9e8f97aSAdrien Destugues B_TRANSLATE("The screen mode could not be set:\n\t%s\n"), 1460c9e8f97aSAdrien Destugues screen_errors(status)); 1461551c9f15SSiarzhuk Zharski BAlert* alert = new BAlert(B_TRANSLATE("Warning"), message, 1462c9e8f97aSAdrien Destugues B_TRANSLATE("OK"), NULL, NULL, 146307184a9eSAxel Dörfler B_WIDTH_AS_USUAL, B_WARNING_ALERT); 1464aed35104SHumdinger alert->SetFlags(alert->Flags() | B_CLOSE_ON_ESCAPE); 146507184a9eSAxel Dörfler alert->Go(); 1466a10cf76eSAxel Dörfler } 146707184a9eSAxel Dörfler } 1468