1a10cf76eSAxel Dörfler /* 27e44de36SRene Gollent * Copyright 2001-2012, 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 97e44de36SRene Gollent * Rene Gollent, rene@gollent.com 10a10cf76eSAxel Dörfler * Thomas Kurschel 11a10cf76eSAxel Dörfler * Axel Dörfler, axeld@pinc-software.de 12df3f5bacSStephan Aßmus * Stephan Aßmus <superstippi@gmx.de> 13b72c4836SAlexandre Deckner * Alexandre Deckner, alex@zappotek.com 14a10cf76eSAxel Dörfler */ 15a10cf76eSAxel Dörfler 16a10cf76eSAxel Dörfler 17b21d610eSAxel Dörfler #include "ScreenWindow.h" 18b21d610eSAxel Dörfler 19b21d610eSAxel Dörfler #include <stdio.h> 20b21d610eSAxel Dörfler #include <stdlib.h> 21b21d610eSAxel Dörfler #include <string.h> 22b21d610eSAxel Dörfler 23b21d610eSAxel Dörfler #include <Alert.h> 24b21d610eSAxel Dörfler #include <Application.h> 25b21d610eSAxel Dörfler #include <Box.h> 26b21d610eSAxel Dörfler #include <Button.h> 27c9e8f97aSAdrien Destugues #include <Catalog.h> 28b21d610eSAxel Dörfler #include <Directory.h> 29b21d610eSAxel Dörfler #include <File.h> 30b21d610eSAxel Dörfler #include <FindDirectory.h> 31b21d610eSAxel Dörfler #include <InterfaceDefs.h> 32b21d610eSAxel Dörfler #include <LayoutBuilder.h> 33b21d610eSAxel Dörfler #include <MenuBar.h> 34b21d610eSAxel Dörfler #include <MenuItem.h> 35b21d610eSAxel Dörfler #include <MenuField.h> 36b21d610eSAxel Dörfler #include <Messenger.h> 37b21d610eSAxel Dörfler #include <Path.h> 38b21d610eSAxel Dörfler #include <PopUpMenu.h> 39b21d610eSAxel Dörfler #include <Screen.h> 40b21d610eSAxel Dörfler #include <String.h> 41b21d610eSAxel Dörfler #include <StringView.h> 42b21d610eSAxel Dörfler #include <Roster.h> 43b21d610eSAxel Dörfler #include <Window.h> 44b21d610eSAxel Dörfler 45b21d610eSAxel Dörfler #include <InterfacePrivate.h> 46b21d610eSAxel Dörfler 47a10cf76eSAxel Dörfler #include "AlertWindow.h" 48a10cf76eSAxel Dörfler #include "Constants.h" 49a10cf76eSAxel Dörfler #include "RefreshWindow.h" 50a10cf76eSAxel Dörfler #include "MonitorView.h" 51a10cf76eSAxel Dörfler #include "ScreenSettings.h" 52a10cf76eSAxel Dörfler #include "Utility.h" 53a10cf76eSAxel Dörfler 54a10cf76eSAxel Dörfler /* Note, this headers defines a *private* interface to the Radeon accelerant. 55a10cf76eSAxel Dörfler * It's a solution that works with the current BeOS interface that Haiku 56a10cf76eSAxel Dörfler * adopted. 57a10cf76eSAxel Dörfler * However, it's not a nice and clean solution. Don't use this header in any 58a10cf76eSAxel Dörfler * application if you can avoid it. No other driver is using this, or should 59a10cf76eSAxel Dörfler * be using this. 60a10cf76eSAxel Dörfler * It will be replaced as soon as we introduce an updated accelerant interface 61a10cf76eSAxel Dörfler * which may even happen before R1 hits the streets. 62a10cf76eSAxel Dörfler */ 63a10cf76eSAxel Dörfler #include "multimon.h" // the usual: DANGER WILL, ROBINSON! 64a10cf76eSAxel Dörfler 65a10cf76eSAxel Dörfler 66c9e8f97aSAdrien Destugues #undef B_TRANSLATE_CONTEXT 67c9e8f97aSAdrien Destugues #define B_TRANSLATE_CONTEXT "Screen" 68c9e8f97aSAdrien Destugues 69c9e8f97aSAdrien Destugues 7075c92c56SRyan Leavengood const char* kBackgroundsSignature = "application/x-vnd.Haiku-Backgrounds"; 71c5d80d47SAxel Dörfler 72a10cf76eSAxel Dörfler // list of officially supported colour spaces 73a10cf76eSAxel Dörfler static const struct { 74a10cf76eSAxel Dörfler color_space space; 75a10cf76eSAxel Dörfler int32 bits_per_pixel; 76a10cf76eSAxel Dörfler const char* label; 77a10cf76eSAxel Dörfler } kColorSpaces[] = { 7826747978SAdrien Destugues { B_CMAP8, 8, B_TRANSLATE("8 bits/pixel, 256 colors") }, 79c9e8f97aSAdrien Destugues { B_RGB15, 15, B_TRANSLATE("15 bits/pixel, 32768 colors") }, 80c9e8f97aSAdrien Destugues { B_RGB16, 16, B_TRANSLATE("16 bits/pixel, 65536 colors") }, 81c9e8f97aSAdrien Destugues { B_RGB24, 24, B_TRANSLATE("24 bits/pixel, 16 Million colors") }, 82c9e8f97aSAdrien Destugues { B_RGB32, 32, B_TRANSLATE("32 bits/pixel, 16 Million colors") } 83a10cf76eSAxel Dörfler }; 84b21d610eSAxel Dörfler static const int32 kColorSpaceCount 85b21d610eSAxel Dörfler = sizeof(kColorSpaces) / sizeof(kColorSpaces[0]); 86a10cf76eSAxel Dörfler 87a10cf76eSAxel Dörfler // list of standard refresh rates 88a796facfSAxel Dörfler static const int32 kRefreshRates[] = { 60, 70, 72, 75, 80, 85, 95, 100 }; 89b21d610eSAxel Dörfler static const int32 kRefreshRateCount 90b21d610eSAxel Dörfler = sizeof(kRefreshRates) / sizeof(kRefreshRates[0]); 91a10cf76eSAxel Dörfler 92a10cf76eSAxel Dörfler // list of combine modes 93a10cf76eSAxel Dörfler static const struct { 94a10cf76eSAxel Dörfler combine_mode mode; 95a10cf76eSAxel Dörfler const char *name; 96a10cf76eSAxel Dörfler } kCombineModes[] = { 97c9e8f97aSAdrien Destugues { kCombineDisable, B_TRANSLATE("disable") }, 98c9e8f97aSAdrien Destugues { kCombineHorizontally, B_TRANSLATE("horizontally") }, 99c9e8f97aSAdrien Destugues { kCombineVertically, B_TRANSLATE("vertically") } 100a10cf76eSAxel Dörfler }; 101b21d610eSAxel Dörfler static const int32 kCombineModeCount 102b21d610eSAxel Dörfler = sizeof(kCombineModes) / sizeof(kCombineModes[0]); 10329e8a73aSAxel Dörfler 104a10cf76eSAxel Dörfler 105a10cf76eSAxel Dörfler static BString 106a10cf76eSAxel Dörfler tv_standard_to_string(uint32 mode) 107a10cf76eSAxel Dörfler { 108a10cf76eSAxel Dörfler switch (mode) { 109a10cf76eSAxel Dörfler case 0: return "disabled"; 110a10cf76eSAxel Dörfler case 1: return "NTSC"; 111a10cf76eSAxel Dörfler case 2: return "NTSC Japan"; 112a10cf76eSAxel Dörfler case 3: return "PAL BDGHI"; 113a10cf76eSAxel Dörfler case 4: return "PAL M"; 114a10cf76eSAxel Dörfler case 5: return "PAL N"; 115a10cf76eSAxel Dörfler case 6: return "SECAM"; 116a10cf76eSAxel Dörfler case 101: return "NTSC 443"; 117a10cf76eSAxel Dörfler case 102: return "PAL 60"; 118a10cf76eSAxel Dörfler case 103: return "PAL NC"; 119a10cf76eSAxel Dörfler default: 120a10cf76eSAxel Dörfler { 121a10cf76eSAxel Dörfler BString name; 122a10cf76eSAxel Dörfler name << "??? (" << mode << ")"; 123a10cf76eSAxel Dörfler 124a10cf76eSAxel Dörfler return name; 125a10cf76eSAxel Dörfler } 126a10cf76eSAxel Dörfler } 127a10cf76eSAxel Dörfler } 128a10cf76eSAxel Dörfler 129a10cf76eSAxel Dörfler 130a10cf76eSAxel Dörfler static void 131a10cf76eSAxel Dörfler resolution_to_string(screen_mode& mode, BString &string) 132a10cf76eSAxel Dörfler { 133a10cf76eSAxel Dörfler string << mode.width << " x " << mode.height; 134a10cf76eSAxel Dörfler } 135a10cf76eSAxel Dörfler 136a10cf76eSAxel Dörfler 137a10cf76eSAxel Dörfler static void 138a10cf76eSAxel Dörfler refresh_rate_to_string(float refresh, BString &string, 139a10cf76eSAxel Dörfler bool appendUnit = true, bool alwaysWithFraction = false) 140a10cf76eSAxel Dörfler { 1418bf23e3cSAxel Dörfler snprintf(string.LockBuffer(32), 32, "%.*g", refresh >= 100.0 ? 4 : 3, 1428bf23e3cSAxel Dörfler refresh); 143a10cf76eSAxel Dörfler string.UnlockBuffer(); 144a10cf76eSAxel Dörfler 145a10cf76eSAxel Dörfler if (appendUnit) 146551c9f15SSiarzhuk Zharski string << " " << B_TRANSLATE("Hz"); 147a10cf76eSAxel Dörfler } 148a10cf76eSAxel Dörfler 149a10cf76eSAxel Dörfler 15007184a9eSAxel Dörfler static const char* 15107184a9eSAxel Dörfler screen_errors(status_t status) 15207184a9eSAxel Dörfler { 15307184a9eSAxel Dörfler switch (status) { 15407184a9eSAxel Dörfler case B_ENTRY_NOT_FOUND: 155c9e8f97aSAdrien Destugues return B_TRANSLATE("Unknown mode"); 15607184a9eSAxel Dörfler // TODO: add more? 15707184a9eSAxel Dörfler 15807184a9eSAxel Dörfler default: 15907184a9eSAxel Dörfler return strerror(status); 16007184a9eSAxel Dörfler } 16107184a9eSAxel Dörfler } 16207184a9eSAxel Dörfler 16329e8a73aSAxel Dörfler 1643dfd20c0SStephan Aßmus // #pragma mark - 1653dfd20c0SStephan Aßmus 1663dfd20c0SStephan Aßmus 1675a78744bSAxel Dörfler ScreenWindow::ScreenWindow(ScreenSettings* settings) 168b21d610eSAxel Dörfler : 169560ff447SJonas Sundström BWindow(settings->WindowFrame(), B_TRANSLATE_SYSTEM_NAME("Screen"), 170958e0ca5SJohn Scipione B_TITLED_WINDOW, B_NOT_RESIZABLE | B_NOT_ZOOMABLE 171958e0ca5SJohn Scipione | B_AUTO_UPDATE_SIZE_LIMITS, B_ALL_WORKSPACES), 1723f953a72SAxel Dörfler fIsVesa(false), 173199893c3SAxel Dörfler fBootWorkspaceApplied(false), 1747e44de36SRene Gollent fOtherRefresh(NULL), 175294a85aaSRene Gollent fScreenMode(this), 17661c5c89bSAxel Dörfler fUndoScreenMode(this), 177abc649b8SWaldemar Kornewald fModified(false) 178a10cf76eSAxel Dörfler { 179a10cf76eSAxel Dörfler BScreen screen(this); 180a10cf76eSAxel Dörfler 18112580984SAxel Dörfler accelerant_device_info info; 182d1516993SAxel Dörfler if (screen.GetDeviceInfo(&info) == B_OK 183d1516993SAxel Dörfler && !strcasecmp(info.chipset, "VESA")) 18412580984SAxel Dörfler fIsVesa = true; 18512580984SAxel Dörfler 1865de171daSAxel Dörfler _UpdateOriginal(); 1871fc4cb1fSAxel Dörfler _BuildSupportedColorSpaces(); 188a10cf76eSAxel Dörfler fActive = fSelected = fOriginal; 189a10cf76eSAxel Dörfler 1905a78744bSAxel Dörfler fSettings = settings; 1915a78744bSAxel Dörfler 1925a78744bSAxel Dörfler // we need the "Current Workspace" first to get its height 1935a78744bSAxel Dörfler 194c9e8f97aSAdrien Destugues BPopUpMenu *popUpMenu = new BPopUpMenu(B_TRANSLATE("Current workspace"), 195c9e8f97aSAdrien Destugues true, true); 196c9e8f97aSAdrien Destugues fAllWorkspacesItem = new BMenuItem(B_TRANSLATE("All workspaces"), 197d1516993SAxel Dörfler new BMessage(WORKSPACE_CHECK_MSG)); 1985a78744bSAxel Dörfler popUpMenu->AddItem(fAllWorkspacesItem); 199c9e8f97aSAdrien Destugues BMenuItem *item = new BMenuItem(B_TRANSLATE("Current workspace"), 200d1516993SAxel Dörfler new BMessage(WORKSPACE_CHECK_MSG)); 201b72c4836SAlexandre Deckner 2025a78744bSAxel Dörfler popUpMenu->AddItem(item); 20327c43a2dSRene Gollent fAllWorkspacesItem->SetMarked(true); 2045a78744bSAxel Dörfler 205b21d610eSAxel Dörfler BMenuField* workspaceMenuField = new BMenuField("WorkspaceMenu", NULL, 20610dfe897SAxel Dörfler popUpMenu); 2075a78744bSAxel Dörfler workspaceMenuField->ResizeToPreferred(); 208a10cf76eSAxel Dörfler 209a10cf76eSAxel Dörfler // box on the left with workspace count and monitor view 210a10cf76eSAxel Dörfler 211b21d610eSAxel Dörfler BBox* screenBox = new BBox("screen box"); 2128bf23e3cSAxel Dörfler BGroupLayout* layout = new BGroupLayout(B_VERTICAL, 5.0); 213b21d610eSAxel Dörfler layout->SetInsets(10, 10, 10, 10); 214b21d610eSAxel Dörfler screenBox->SetLayout(layout); 215a10cf76eSAxel Dörfler 21612966d04SAxel Dörfler fMonitorInfo = new BStringView("monitor info", ""); 21712966d04SAxel Dörfler screenBox->AddChild(fMonitorInfo); 21812966d04SAxel Dörfler 219c9e8f97aSAdrien Destugues fMonitorView = new MonitorView(BRect(0.0, 0.0, 80.0, 80.0), 220551c9f15SSiarzhuk Zharski "monitor", screen.Frame().IntegerWidth() + 1, 221c9e8f97aSAdrien Destugues screen.Frame().IntegerHeight() + 1); 222b21d610eSAxel Dörfler screenBox->AddChild(fMonitorView); 2235a78744bSAxel Dörfler 224c9e8f97aSAdrien Destugues fColumnsControl = new BTextControl(B_TRANSLATE("Columns:"), "0", 225b21d610eSAxel Dörfler new BMessage(kMsgWorkspaceColumnsChanged)); 226c9e8f97aSAdrien Destugues fRowsControl = new BTextControl(B_TRANSLATE("Rows:"), "0", 227b21d610eSAxel Dörfler new BMessage(kMsgWorkspaceRowsChanged)); 228b21d610eSAxel Dörfler 229b21d610eSAxel Dörfler screenBox->AddChild(BLayoutBuilder::Grid<>(5.0, 5.0) 230c9e8f97aSAdrien Destugues .Add(new BStringView("", B_TRANSLATE("Workspaces")), 0, 0, 3) 231b21d610eSAxel Dörfler .AddTextControl(fColumnsControl, 0, 1, B_ALIGN_RIGHT) 232b21d610eSAxel Dörfler .AddGroup(B_HORIZONTAL, 0, 2, 1) 233b21d610eSAxel Dörfler .Add(_CreateColumnRowButton(true, false)) 234b21d610eSAxel Dörfler .Add(_CreateColumnRowButton(true, true)) 235b21d610eSAxel Dörfler .End() 236b21d610eSAxel Dörfler .AddTextControl(fRowsControl, 0, 2, B_ALIGN_RIGHT) 237b21d610eSAxel Dörfler .AddGroup(B_HORIZONTAL, 0, 2, 2) 238b21d610eSAxel Dörfler .Add(_CreateColumnRowButton(false, false)) 239b21d610eSAxel Dörfler .Add(_CreateColumnRowButton(false, true)) 24025fd5c7bSAlex Wilson .End() 24125fd5c7bSAlex Wilson .View()); 242b21d610eSAxel Dörfler 243b21d610eSAxel Dörfler fBackgroundsButton = new BButton("BackgroundsButton", 244c9e8f97aSAdrien Destugues B_TRANSLATE("Set background" B_UTF8_ELLIPSIS), 245b21d610eSAxel Dörfler new BMessage(BUTTON_LAUNCH_BACKGROUNDS_MSG)); 246b21d610eSAxel Dörfler fBackgroundsButton->SetFontSize(be_plain_font->Size() * 0.9); 247b21d610eSAxel Dörfler screenBox->AddChild(fBackgroundsButton); 248a10cf76eSAxel Dörfler 249a10cf76eSAxel Dörfler // box on the right with screen resolution, etc. 250a10cf76eSAxel Dörfler 251b21d610eSAxel Dörfler BBox* controlsBox = new BBox("controls box"); 252b21d610eSAxel Dörfler controlsBox->SetLabel(workspaceMenuField); 25325fd5c7bSAlex Wilson BGroupView* outerControlsView = new BGroupView(B_VERTICAL, 10.0); 25425fd5c7bSAlex Wilson outerControlsView->GroupLayout()->SetInsets(10, 10, 10, 10); 255b21d610eSAxel Dörfler controlsBox->AddChild(outerControlsView); 256a10cf76eSAxel Dörfler 257551c9f15SSiarzhuk Zharski fResolutionMenu = new BPopUpMenu("resolution", true, true); 258a10cf76eSAxel Dörfler 25966ab1666SAxel Dörfler uint16 maxWidth = 0; 26066ab1666SAxel Dörfler uint16 maxHeight = 0; 26166ab1666SAxel Dörfler uint16 previousWidth = 0; 26266ab1666SAxel Dörfler uint16 previousHeight = 0; 263a10cf76eSAxel Dörfler for (int32 i = 0; i < fScreenMode.CountModes(); i++) { 264a10cf76eSAxel Dörfler screen_mode mode = fScreenMode.ModeAt(i); 265a10cf76eSAxel Dörfler 266a10cf76eSAxel Dörfler if (mode.width == previousWidth && mode.height == previousHeight) 267a10cf76eSAxel Dörfler continue; 268a10cf76eSAxel Dörfler 269a10cf76eSAxel Dörfler previousWidth = mode.width; 270a10cf76eSAxel Dörfler previousHeight = mode.height; 27166ab1666SAxel Dörfler if (maxWidth < mode.width) 27266ab1666SAxel Dörfler maxWidth = mode.width; 27366ab1666SAxel Dörfler if (maxHeight < mode.height) 27466ab1666SAxel Dörfler maxHeight = mode.height; 275a10cf76eSAxel Dörfler 276a10cf76eSAxel Dörfler BMessage* message = new BMessage(POP_RESOLUTION_MSG); 277a10cf76eSAxel Dörfler message->AddInt32("width", mode.width); 278a10cf76eSAxel Dörfler message->AddInt32("height", mode.height); 279a10cf76eSAxel Dörfler 280a10cf76eSAxel Dörfler BString name; 281a10cf76eSAxel Dörfler name << mode.width << " x " << mode.height; 282a10cf76eSAxel Dörfler 283a10cf76eSAxel Dörfler fResolutionMenu->AddItem(new BMenuItem(name.String(), message)); 284a10cf76eSAxel Dörfler } 285a10cf76eSAxel Dörfler 28666ab1666SAxel Dörfler fMonitorView->SetMaxResolution(maxWidth, maxHeight); 28766ab1666SAxel Dörfler 288c9e8f97aSAdrien Destugues fResolutionField = new BMenuField("ResolutionMenu", 28910dfe897SAxel Dörfler B_TRANSLATE("Resolution:"), fResolutionMenu); 290a10cf76eSAxel Dörfler 291551c9f15SSiarzhuk Zharski fColorsMenu = new BPopUpMenu("colors", true, false); 292a10cf76eSAxel Dörfler 293a10cf76eSAxel Dörfler for (int32 i = 0; i < kColorSpaceCount; i++) { 2941fc4cb1fSAxel Dörfler if ((fSupportedColorSpaces & (1 << i)) == 0) 2951fc4cb1fSAxel Dörfler continue; 2961fc4cb1fSAxel Dörfler 297a10cf76eSAxel Dörfler BMessage* message = new BMessage(POP_COLORS_MSG); 298a10cf76eSAxel Dörfler message->AddInt32("bits_per_pixel", kColorSpaces[i].bits_per_pixel); 299a10cf76eSAxel Dörfler message->AddInt32("space", kColorSpaces[i].space); 300a10cf76eSAxel Dörfler 3011fc4cb1fSAxel Dörfler BMenuItem* item = new BMenuItem(kColorSpaces[i].label, message); 3021fc4cb1fSAxel Dörfler if (kColorSpaces[i].space == screen.ColorSpace()) 3031fc4cb1fSAxel Dörfler fUserSelectedColorSpace = item; 3041fc4cb1fSAxel Dörfler 3051fc4cb1fSAxel Dörfler fColorsMenu->AddItem(item); 306a10cf76eSAxel Dörfler } 307a10cf76eSAxel Dörfler 308c9e8f97aSAdrien Destugues fColorsField = new BMenuField("ColorsMenu", B_TRANSLATE("Colors:"), 30910dfe897SAxel Dörfler fColorsMenu); 310a10cf76eSAxel Dörfler 311551c9f15SSiarzhuk Zharski fRefreshMenu = new BPopUpMenu("refresh rate", true, true); 312a10cf76eSAxel Dörfler 31329e8a73aSAxel Dörfler float min, max; 31429e8a73aSAxel Dörfler if (fScreenMode.GetRefreshLimits(fActive, min, max) && min == max) { 31529e8a73aSAxel Dörfler // This is a special case for drivers that only support a single 31629e8a73aSAxel Dörfler // frequency, like the VESA driver 31729e8a73aSAxel Dörfler BString name; 3187e44de36SRene Gollent refresh_rate_to_string(min, name); 319*0efb8b66SJerome Duval BMenuItem *item = new BMenuItem(name.String(), NULL); 320*0efb8b66SJerome Duval fRefreshMenu->AddItem(item); 32129e8a73aSAxel Dörfler item->SetEnabled(false); 32229e8a73aSAxel Dörfler } else { 32370a2b1b5SAxel Dörfler monitor_info info; 32470a2b1b5SAxel Dörfler if (fScreenMode.GetMonitorInfo(info) == B_OK) { 32570a2b1b5SAxel Dörfler min = max_c(info.min_vertical_frequency, min); 32670a2b1b5SAxel Dörfler max = min_c(info.max_vertical_frequency, max); 32770a2b1b5SAxel Dörfler } 32870a2b1b5SAxel Dörfler 329a10cf76eSAxel Dörfler for (int32 i = 0; i < kRefreshRateCount; ++i) { 33070a2b1b5SAxel Dörfler if (kRefreshRates[i] < min || kRefreshRates[i] > max) 33170a2b1b5SAxel Dörfler continue; 33270a2b1b5SAxel Dörfler 333a10cf76eSAxel Dörfler BString name; 334551c9f15SSiarzhuk Zharski name << kRefreshRates[i] << " " << B_TRANSLATE("Hz"); 335a10cf76eSAxel Dörfler 336*0efb8b66SJerome Duval BMessage *message = new BMessage(POP_REFRESH_MSG); 337a10cf76eSAxel Dörfler message->AddFloat("refresh", kRefreshRates[i]); 338a10cf76eSAxel Dörfler 339a10cf76eSAxel Dörfler fRefreshMenu->AddItem(new BMenuItem(name.String(), message)); 340a10cf76eSAxel Dörfler } 341a10cf76eSAxel Dörfler 342c9e8f97aSAdrien Destugues fOtherRefresh = new BMenuItem(B_TRANSLATE("Other" B_UTF8_ELLIPSIS), 343*0efb8b66SJerome Duval new BMessage(POP_OTHER_REFRESH_MSG)); 344a10cf76eSAxel Dörfler fRefreshMenu->AddItem(fOtherRefresh); 34529e8a73aSAxel Dörfler } 346a10cf76eSAxel Dörfler 347c9e8f97aSAdrien Destugues fRefreshField = new BMenuField("RefreshMenu", B_TRANSLATE("Refresh rate:"), 34810dfe897SAxel Dörfler fRefreshMenu); 349b21d610eSAxel Dörfler 35012580984SAxel Dörfler if (_IsVesa()) 35112580984SAxel Dörfler fRefreshField->Hide(); 352a10cf76eSAxel Dörfler 353a10cf76eSAxel Dörfler // enlarged area for multi-monitor settings 354a10cf76eSAxel Dörfler { 355a10cf76eSAxel Dörfler bool dummy; 356a10cf76eSAxel Dörfler uint32 dummy32; 357a10cf76eSAxel Dörfler bool multiMonSupport; 358a10cf76eSAxel Dörfler bool useLaptopPanelSupport; 359a10cf76eSAxel Dörfler bool tvStandardSupport; 360a10cf76eSAxel Dörfler 361a10cf76eSAxel Dörfler multiMonSupport = TestMultiMonSupport(&screen) == B_OK; 362a10cf76eSAxel Dörfler useLaptopPanelSupport = GetUseLaptopPanel(&screen, &dummy) == B_OK; 363a10cf76eSAxel Dörfler tvStandardSupport = GetTVStandard(&screen, &dummy32) == B_OK; 364a10cf76eSAxel Dörfler 365a10cf76eSAxel Dörfler // even if there is no support, we still create all controls 366a10cf76eSAxel Dörfler // to make sure we don't access NULL pointers later on 367a10cf76eSAxel Dörfler 368551c9f15SSiarzhuk Zharski fCombineMenu = new BPopUpMenu("CombineDisplays", 369c9e8f97aSAdrien Destugues true, true); 370a10cf76eSAxel Dörfler 371a10cf76eSAxel Dörfler for (int32 i = 0; i < kCombineModeCount; i++) { 372*0efb8b66SJerome Duval BMessage *message = new BMessage(POP_COMBINE_DISPLAYS_MSG); 373a10cf76eSAxel Dörfler message->AddInt32("mode", kCombineModes[i].mode); 374a10cf76eSAxel Dörfler 375d1516993SAxel Dörfler fCombineMenu->AddItem(new BMenuItem(kCombineModes[i].name, 376d1516993SAxel Dörfler message)); 377a10cf76eSAxel Dörfler } 378a10cf76eSAxel Dörfler 379b21d610eSAxel Dörfler fCombineField = new BMenuField("CombineMenu", 38010dfe897SAxel Dörfler B_TRANSLATE("Combine displays:"), fCombineMenu); 381a10cf76eSAxel Dörfler 382a10cf76eSAxel Dörfler if (!multiMonSupport) 383df3f5bacSStephan Aßmus fCombineField->Hide(); 384a10cf76eSAxel Dörfler 385551c9f15SSiarzhuk Zharski fSwapDisplaysMenu = new BPopUpMenu("SwapDisplays", 386c9e8f97aSAdrien Destugues true, true); 387a10cf76eSAxel Dörfler 388a10cf76eSAxel Dörfler // !order is important - we rely that boolean value == idx 389*0efb8b66SJerome Duval BMessage *message = new BMessage(POP_SWAP_DISPLAYS_MSG); 390a10cf76eSAxel Dörfler message->AddBool("swap", false); 391c9e8f97aSAdrien Destugues fSwapDisplaysMenu->AddItem(new BMenuItem(B_TRANSLATE("no"), message)); 392a10cf76eSAxel Dörfler 393a10cf76eSAxel Dörfler message = new BMessage(POP_SWAP_DISPLAYS_MSG); 394a10cf76eSAxel Dörfler message->AddBool("swap", true); 395c9e8f97aSAdrien Destugues fSwapDisplaysMenu->AddItem(new BMenuItem(B_TRANSLATE("yes"), message)); 396a10cf76eSAxel Dörfler 397c9e8f97aSAdrien Destugues fSwapDisplaysField = new BMenuField("SwapMenu", 39810dfe897SAxel Dörfler B_TRANSLATE("Swap displays:"), fSwapDisplaysMenu); 399a10cf76eSAxel Dörfler 400a10cf76eSAxel Dörfler if (!multiMonSupport) 401df3f5bacSStephan Aßmus fSwapDisplaysField->Hide(); 402a10cf76eSAxel Dörfler 403551c9f15SSiarzhuk Zharski fUseLaptopPanelMenu = new BPopUpMenu("UseLaptopPanel", 404c9e8f97aSAdrien Destugues true, true); 405a10cf76eSAxel Dörfler 406a10cf76eSAxel Dörfler // !order is important - we rely that boolean value == idx 407a10cf76eSAxel Dörfler message = new BMessage(POP_USE_LAPTOP_PANEL_MSG); 408a10cf76eSAxel Dörfler message->AddBool("use", false); 409c9e8f97aSAdrien Destugues fUseLaptopPanelMenu->AddItem(new BMenuItem(B_TRANSLATE("if needed"), 410c9e8f97aSAdrien Destugues message)); 411a10cf76eSAxel Dörfler 412a10cf76eSAxel Dörfler message = new BMessage(POP_USE_LAPTOP_PANEL_MSG); 413a10cf76eSAxel Dörfler message->AddBool("use", true); 414c9e8f97aSAdrien Destugues fUseLaptopPanelMenu->AddItem(new BMenuItem(B_TRANSLATE("always"), 415c9e8f97aSAdrien Destugues message)); 416a10cf76eSAxel Dörfler 417b21d610eSAxel Dörfler fUseLaptopPanelField = new BMenuField("UseLaptopPanel", 41810dfe897SAxel Dörfler B_TRANSLATE("Use laptop panel:"), fUseLaptopPanelMenu); 419a10cf76eSAxel Dörfler 420a10cf76eSAxel Dörfler if (!useLaptopPanelSupport) 421df3f5bacSStephan Aßmus fUseLaptopPanelField->Hide(); 422a10cf76eSAxel Dörfler 423551c9f15SSiarzhuk Zharski fTVStandardMenu = new BPopUpMenu("TVStandard", true, true); 424a10cf76eSAxel Dörfler 425a10cf76eSAxel Dörfler // arbitrary limit 426a10cf76eSAxel Dörfler uint32 i; 427a10cf76eSAxel Dörfler for (i = 0; i < 100; ++i) { 428a10cf76eSAxel Dörfler uint32 mode; 429a10cf76eSAxel Dörfler if (GetNthSupportedTVStandard(&screen, i, &mode) != B_OK) 430a10cf76eSAxel Dörfler break; 431a10cf76eSAxel Dörfler 432a10cf76eSAxel Dörfler BString name = tv_standard_to_string(mode); 433a10cf76eSAxel Dörfler 434a10cf76eSAxel Dörfler message = new BMessage(POP_TV_STANDARD_MSG); 435a10cf76eSAxel Dörfler message->AddInt32("tv_standard", mode); 436a10cf76eSAxel Dörfler 437a10cf76eSAxel Dörfler fTVStandardMenu->AddItem(new BMenuItem(name.String(), message)); 438a10cf76eSAxel Dörfler } 439a10cf76eSAxel Dörfler 440c9e8f97aSAdrien Destugues fTVStandardField = new BMenuField("tv standard", 44110dfe897SAxel Dörfler B_TRANSLATE("Video format:"), fTVStandardMenu); 442df3f5bacSStephan Aßmus fTVStandardField->SetAlignment(B_ALIGN_RIGHT); 443a10cf76eSAxel Dörfler 444b21d610eSAxel Dörfler if (!tvStandardSupport || i == 0) 445df3f5bacSStephan Aßmus fTVStandardField->Hide(); 446a10cf76eSAxel Dörfler } 447a10cf76eSAxel Dörfler 44825fd5c7bSAlex Wilson BLayoutBuilder::Group<>(outerControlsView) 44925fd5c7bSAlex Wilson .AddGrid(5.0, 5.0) 450b21d610eSAxel Dörfler .AddMenuField(fResolutionField, 0, 0, B_ALIGN_RIGHT) 451b21d610eSAxel Dörfler .AddMenuField(fColorsField, 0, 1, B_ALIGN_RIGHT) 452b21d610eSAxel Dörfler .AddMenuField(fRefreshField, 0, 2, B_ALIGN_RIGHT) 453b21d610eSAxel Dörfler .AddMenuField(fCombineField, 0, 3, B_ALIGN_RIGHT) 454b21d610eSAxel Dörfler .AddMenuField(fSwapDisplaysField, 0, 4, B_ALIGN_RIGHT) 455b21d610eSAxel Dörfler .AddMenuField(fUseLaptopPanelField, 0, 5, B_ALIGN_RIGHT) 45625fd5c7bSAlex Wilson .AddMenuField(fTVStandardField, 0, 6, B_ALIGN_RIGHT) 45725fd5c7bSAlex Wilson .End(); 458df3f5bacSStephan Aßmus 459abc649b8SWaldemar Kornewald // TODO: we don't support getting the screen's preferred settings 460abc649b8SWaldemar Kornewald /* fDefaultsButton = new BButton(buttonRect, "DefaultsButton", "Defaults", 461b21d610eSAxel Dörfler new BMessage(BUTTON_DEFAULTS_MSG));*/ 462a10cf76eSAxel Dörfler 463c9e8f97aSAdrien Destugues fApplyButton = new BButton("ApplyButton", B_TRANSLATE("Apply"), 464df3f5bacSStephan Aßmus new BMessage(BUTTON_APPLY_MSG)); 465df3f5bacSStephan Aßmus fApplyButton->SetEnabled(false); 46625fd5c7bSAlex Wilson BLayoutBuilder::Group<>(outerControlsView) 467b21d610eSAxel Dörfler .AddGlue() 46825fd5c7bSAlex Wilson .AddGroup(B_HORIZONTAL) 46925fd5c7bSAlex Wilson .AddGlue() 47025fd5c7bSAlex Wilson .Add(fApplyButton); 471b21d610eSAxel Dörfler 472c9e8f97aSAdrien Destugues fRevertButton = new BButton("RevertButton", B_TRANSLATE("Revert"), 473b21d610eSAxel Dörfler new BMessage(BUTTON_REVERT_MSG)); 474b21d610eSAxel Dörfler fRevertButton->SetEnabled(false); 475b21d610eSAxel Dörfler 47625fd5c7bSAlex Wilson BLayoutBuilder::Group<>(this, B_VERTICAL, 10.0) 477b21d610eSAxel Dörfler .SetInsets(10, 10, 10, 10) 478b21d610eSAxel Dörfler .AddGroup(B_HORIZONTAL, 10.0) 479b21d610eSAxel Dörfler .AddGroup(B_VERTICAL) 480958e0ca5SJohn Scipione .AddStrut(floor(controlsBox->TopBorderOffset() / 16) - 1) 481b21d610eSAxel Dörfler .Add(screenBox) 482b21d610eSAxel Dörfler .End() 483b21d610eSAxel Dörfler .Add(controlsBox) 484b21d610eSAxel Dörfler .End() 485b21d610eSAxel Dörfler .AddGroup(B_HORIZONTAL, 10.0) 486b21d610eSAxel Dörfler .Add(fRevertButton) 487b21d610eSAxel Dörfler .AddGlue(); 488b21d610eSAxel Dörfler 4895de171daSAxel Dörfler _UpdateControls(); 49012966d04SAxel Dörfler _UpdateMonitor(); 491a10cf76eSAxel Dörfler } 492a10cf76eSAxel Dörfler 493a10cf76eSAxel Dörfler 494a10cf76eSAxel Dörfler ScreenWindow::~ScreenWindow() 495a10cf76eSAxel Dörfler { 496a10cf76eSAxel Dörfler delete fSettings; 497a10cf76eSAxel Dörfler } 498a10cf76eSAxel Dörfler 499a10cf76eSAxel Dörfler 500a10cf76eSAxel Dörfler bool 501a10cf76eSAxel Dörfler ScreenWindow::QuitRequested() 502a10cf76eSAxel Dörfler { 503a10cf76eSAxel Dörfler fSettings->SetWindowFrame(Frame()); 504199893c3SAxel Dörfler 505199893c3SAxel Dörfler // Write mode of workspace 0 (the boot workspace) to the vesa settings file 506199893c3SAxel Dörfler screen_mode vesaMode; 507199893c3SAxel Dörfler if (fBootWorkspaceApplied && fScreenMode.Get(vesaMode, 0) == B_OK) { 508199893c3SAxel Dörfler status_t status = _WriteVesaModeFile(vesaMode); 50912580984SAxel Dörfler if (status < B_OK) { 510c9e8f97aSAdrien Destugues BString warning = B_TRANSLATE("Could not write VESA mode settings" 511c9e8f97aSAdrien Destugues " file:\n\t"); 51212580984SAxel Dörfler warning << strerror(status); 513551c9f15SSiarzhuk Zharski (new BAlert(B_TRANSLATE("Warning"), warning.String(), B_TRANSLATE("OK"), NULL, 514c9e8f97aSAdrien Destugues NULL, B_WIDTH_AS_USUAL, B_WARNING_ALERT))->Go(); 51512580984SAxel Dörfler } 51612580984SAxel Dörfler } 51712580984SAxel Dörfler 518a10cf76eSAxel Dörfler be_app->PostMessage(B_QUIT_REQUESTED); 519a10cf76eSAxel Dörfler 520a10cf76eSAxel Dörfler return BWindow::QuitRequested(); 521a10cf76eSAxel Dörfler } 522a10cf76eSAxel Dörfler 523a10cf76eSAxel Dörfler 5245de171daSAxel Dörfler /*! Update resolution list according to combine mode 5251fc4cb1fSAxel Dörfler (some resolutions may not be combinable due to memory restrictions). 526a10cf76eSAxel Dörfler */ 527a10cf76eSAxel Dörfler void 5285de171daSAxel Dörfler ScreenWindow::_CheckResolutionMenu() 529a10cf76eSAxel Dörfler { 530a10cf76eSAxel Dörfler for (int32 i = 0; i < fResolutionMenu->CountItems(); i++) 531a10cf76eSAxel Dörfler fResolutionMenu->ItemAt(i)->SetEnabled(false); 532a10cf76eSAxel Dörfler 533a10cf76eSAxel Dörfler for (int32 i = 0; i < fScreenMode.CountModes(); i++) { 534a10cf76eSAxel Dörfler screen_mode mode = fScreenMode.ModeAt(i); 535a10cf76eSAxel Dörfler if (mode.combine != fSelected.combine) 536a10cf76eSAxel Dörfler continue; 537a10cf76eSAxel Dörfler 538a10cf76eSAxel Dörfler BString name; 539a10cf76eSAxel Dörfler name << mode.width << " x " << mode.height; 540a10cf76eSAxel Dörfler 541a10cf76eSAxel Dörfler BMenuItem *item = fResolutionMenu->FindItem(name.String()); 542a10cf76eSAxel Dörfler if (item != NULL) 543a10cf76eSAxel Dörfler item->SetEnabled(true); 544a10cf76eSAxel Dörfler } 545a10cf76eSAxel Dörfler } 546a10cf76eSAxel Dörfler 547a10cf76eSAxel Dörfler 5485de171daSAxel Dörfler /*! Update color and refresh options according to current mode 5495de171daSAxel Dörfler (a color space is made active if there is any mode with 5505de171daSAxel Dörfler given resolution and this colour space; same applies for 5515de171daSAxel Dörfler refresh rate, though "Other…" is always possible) 552a10cf76eSAxel Dörfler */ 553a10cf76eSAxel Dörfler void 5545de171daSAxel Dörfler ScreenWindow::_CheckColorMenu() 555a10cf76eSAxel Dörfler { 5561fc4cb1fSAxel Dörfler int32 supportsAnything = false; 5571fc4cb1fSAxel Dörfler int32 index = 0; 5581fc4cb1fSAxel Dörfler 559a10cf76eSAxel Dörfler for (int32 i = 0; i < kColorSpaceCount; i++) { 5601fc4cb1fSAxel Dörfler if ((fSupportedColorSpaces & (1 << i)) == 0) 5611fc4cb1fSAxel Dörfler continue; 5621fc4cb1fSAxel Dörfler 563a10cf76eSAxel Dörfler bool supported = false; 564a10cf76eSAxel Dörfler 565a10cf76eSAxel Dörfler for (int32 j = 0; j < fScreenMode.CountModes(); j++) { 566a10cf76eSAxel Dörfler screen_mode mode = fScreenMode.ModeAt(j); 567a10cf76eSAxel Dörfler 568a10cf76eSAxel Dörfler if (fSelected.width == mode.width 569a10cf76eSAxel Dörfler && fSelected.height == mode.height 5701fc4cb1fSAxel Dörfler && kColorSpaces[i].space == mode.space 571a10cf76eSAxel Dörfler && fSelected.combine == mode.combine) { 5721fc4cb1fSAxel Dörfler supportsAnything = true; 573a10cf76eSAxel Dörfler supported = true; 574a10cf76eSAxel Dörfler break; 575a10cf76eSAxel Dörfler } 576a10cf76eSAxel Dörfler } 577a10cf76eSAxel Dörfler 5781fc4cb1fSAxel Dörfler BMenuItem* item = fColorsMenu->ItemAt(index++); 579a10cf76eSAxel Dörfler if (item) 580a10cf76eSAxel Dörfler item->SetEnabled(supported); 581a10cf76eSAxel Dörfler } 5821fc4cb1fSAxel Dörfler 5831fc4cb1fSAxel Dörfler fColorsField->SetEnabled(supportsAnything); 5841fc4cb1fSAxel Dörfler 5851fc4cb1fSAxel Dörfler if (!supportsAnything) 5861fc4cb1fSAxel Dörfler return; 5871fc4cb1fSAxel Dörfler 5881fc4cb1fSAxel Dörfler // Make sure a valid item is selected 5891fc4cb1fSAxel Dörfler 5901fc4cb1fSAxel Dörfler BMenuItem* item = fColorsMenu->FindMarked(); 5911fc4cb1fSAxel Dörfler bool changed = false; 5921fc4cb1fSAxel Dörfler 5931fc4cb1fSAxel Dörfler if (item != fUserSelectedColorSpace) { 5941fc4cb1fSAxel Dörfler if (fUserSelectedColorSpace != NULL 5951fc4cb1fSAxel Dörfler && fUserSelectedColorSpace->IsEnabled()) { 5961fc4cb1fSAxel Dörfler fUserSelectedColorSpace->SetMarked(true); 5971fc4cb1fSAxel Dörfler item = fUserSelectedColorSpace; 5981fc4cb1fSAxel Dörfler changed = true; 5991fc4cb1fSAxel Dörfler } 6001fc4cb1fSAxel Dörfler } 6011fc4cb1fSAxel Dörfler if (item != NULL && !item->IsEnabled()) { 6021fc4cb1fSAxel Dörfler // find the next best item 6031fc4cb1fSAxel Dörfler int32 index = fColorsMenu->IndexOf(item); 6041fc4cb1fSAxel Dörfler bool found = false; 6051fc4cb1fSAxel Dörfler 6061fc4cb1fSAxel Dörfler for (int32 i = index + 1; i < fColorsMenu->CountItems(); i++) { 6071fc4cb1fSAxel Dörfler item = fColorsMenu->ItemAt(i); 6081fc4cb1fSAxel Dörfler if (item->IsEnabled()) { 6091fc4cb1fSAxel Dörfler found = true; 6101fc4cb1fSAxel Dörfler break; 6111fc4cb1fSAxel Dörfler } 6121fc4cb1fSAxel Dörfler } 6131fc4cb1fSAxel Dörfler if (!found) { 6141fc4cb1fSAxel Dörfler // search backwards as well 6151fc4cb1fSAxel Dörfler for (int32 i = index - 1; i >= 0; i--) { 6161fc4cb1fSAxel Dörfler item = fColorsMenu->ItemAt(i); 6171fc4cb1fSAxel Dörfler if (item->IsEnabled()) 6181fc4cb1fSAxel Dörfler break; 6191fc4cb1fSAxel Dörfler } 6201fc4cb1fSAxel Dörfler } 6211fc4cb1fSAxel Dörfler 6221fc4cb1fSAxel Dörfler item->SetMarked(true); 6231fc4cb1fSAxel Dörfler changed = true; 6241fc4cb1fSAxel Dörfler } 6251fc4cb1fSAxel Dörfler 6261fc4cb1fSAxel Dörfler if (changed) { 6271fc4cb1fSAxel Dörfler // Update selected space 6281fc4cb1fSAxel Dörfler 6291fc4cb1fSAxel Dörfler BMessage* message = item->Message(); 6301fc4cb1fSAxel Dörfler int32 space; 6311fc4cb1fSAxel Dörfler if (message->FindInt32("space", &space) == B_OK) { 6321fc4cb1fSAxel Dörfler fSelected.space = (color_space)space; 6331fc4cb1fSAxel Dörfler _UpdateColorLabel(); 6341fc4cb1fSAxel Dörfler } 6351fc4cb1fSAxel Dörfler } 636a10cf76eSAxel Dörfler } 637a10cf76eSAxel Dörfler 638a10cf76eSAxel Dörfler 6395de171daSAxel Dörfler /*! Enable/disable refresh options according to current mode. */ 640a10cf76eSAxel Dörfler void 6415de171daSAxel Dörfler ScreenWindow::_CheckRefreshMenu() 642a10cf76eSAxel Dörfler { 64329e8a73aSAxel Dörfler float min, max; 64429e8a73aSAxel Dörfler if (fScreenMode.GetRefreshLimits(fSelected, min, max) != B_OK || min == max) 64529e8a73aSAxel Dörfler return; 646a10cf76eSAxel Dörfler 64729e8a73aSAxel Dörfler for (int32 i = fRefreshMenu->CountItems(); i-- > 0;) { 64829e8a73aSAxel Dörfler BMenuItem* item = fRefreshMenu->ItemAt(i); 64929e8a73aSAxel Dörfler BMessage* message = item->Message(); 65029e8a73aSAxel Dörfler float refresh; 65129e8a73aSAxel Dörfler if (message != NULL && message->FindFloat("refresh", &refresh) == B_OK) 65229e8a73aSAxel Dörfler item->SetEnabled(refresh >= min && refresh <= max); 653a10cf76eSAxel Dörfler } 654a10cf76eSAxel Dörfler } 655a10cf76eSAxel Dörfler 656a10cf76eSAxel Dörfler 6575de171daSAxel Dörfler /*! Activate appropriate menu item according to selected refresh rate */ 658a10cf76eSAxel Dörfler void 6595de171daSAxel Dörfler ScreenWindow::_UpdateRefreshControl() 660a10cf76eSAxel Dörfler { 6617e44de36SRene Gollent for (int32 i = 0; i < fRefreshMenu->CountItems(); i++) { 6627e44de36SRene Gollent BMenuItem* item = fRefreshMenu->ItemAt(i); 6637e44de36SRene Gollent if (item->Message()->FindFloat("refresh") == fSelected.refresh) { 664a10cf76eSAxel Dörfler item->SetMarked(true); 66526747978SAdrien Destugues // "Other" items only contains a refresh rate when active 66626747978SAdrien Destugues fOtherRefresh->SetLabel(B_TRANSLATE("Other" B_UTF8_ELLIPSIS)); 667a10cf76eSAxel Dörfler return; 668a10cf76eSAxel Dörfler } 6697e44de36SRene Gollent } 670a10cf76eSAxel Dörfler 671a10cf76eSAxel Dörfler // this is a non-standard refresh rate 6727e44de36SRene Gollent if (fOtherRefresh != NULL) { 673a10cf76eSAxel Dörfler fOtherRefresh->Message()->ReplaceFloat("refresh", fSelected.refresh); 674a10cf76eSAxel Dörfler fOtherRefresh->SetMarked(true); 675a10cf76eSAxel Dörfler 6767e44de36SRene Gollent BString string; 6777e44de36SRene Gollent refresh_rate_to_string(fSelected.refresh, string); 678a10cf76eSAxel Dörfler fRefreshMenu->Superitem()->SetLabel(string.String()); 679a10cf76eSAxel Dörfler 680c9e8f97aSAdrien Destugues string.Append(B_TRANSLATE("/other" B_UTF8_ELLIPSIS)); 681a10cf76eSAxel Dörfler fOtherRefresh->SetLabel(string.String()); 682a10cf76eSAxel Dörfler } 6837e44de36SRene Gollent } 684a10cf76eSAxel Dörfler 685a10cf76eSAxel Dörfler 686a10cf76eSAxel Dörfler void 6875de171daSAxel Dörfler ScreenWindow::_UpdateMonitorView() 688a10cf76eSAxel Dörfler { 689a10cf76eSAxel Dörfler BMessage updateMessage(UPDATE_DESKTOP_MSG); 690a10cf76eSAxel Dörfler updateMessage.AddInt32("width", fSelected.width); 691a10cf76eSAxel Dörfler updateMessage.AddInt32("height", fSelected.height); 692a10cf76eSAxel Dörfler 693a10cf76eSAxel Dörfler PostMessage(&updateMessage, fMonitorView); 694a10cf76eSAxel Dörfler } 695a10cf76eSAxel Dörfler 696a10cf76eSAxel Dörfler 697a10cf76eSAxel Dörfler void 6985de171daSAxel Dörfler ScreenWindow::_UpdateControls() 699a10cf76eSAxel Dörfler { 700b21d610eSAxel Dörfler _UpdateWorkspaceButtons(); 701b21d610eSAxel Dörfler 702a10cf76eSAxel Dörfler BMenuItem* item = fSwapDisplaysMenu->ItemAt((int32)fSelected.swap_displays); 703a10cf76eSAxel Dörfler if (item && !item->IsMarked()) 704a10cf76eSAxel Dörfler item->SetMarked(true); 705a10cf76eSAxel Dörfler 706a10cf76eSAxel Dörfler item = fUseLaptopPanelMenu->ItemAt((int32)fSelected.use_laptop_panel); 707a10cf76eSAxel Dörfler if (item && !item->IsMarked()) 708a10cf76eSAxel Dörfler item->SetMarked(true); 709a10cf76eSAxel Dörfler 710a10cf76eSAxel Dörfler for (int32 i = 0; i < fTVStandardMenu->CountItems(); i++) { 711a10cf76eSAxel Dörfler item = fTVStandardMenu->ItemAt(i); 712a10cf76eSAxel Dörfler 713a10cf76eSAxel Dörfler uint32 tvStandard; 714a10cf76eSAxel Dörfler item->Message()->FindInt32("tv_standard", (int32 *)&tvStandard); 715a10cf76eSAxel Dörfler if (tvStandard == fSelected.tv_standard) { 716a10cf76eSAxel Dörfler if (!item->IsMarked()) 717a10cf76eSAxel Dörfler item->SetMarked(true); 718a10cf76eSAxel Dörfler break; 719a10cf76eSAxel Dörfler } 720a10cf76eSAxel Dörfler } 721a10cf76eSAxel Dörfler 7225de171daSAxel Dörfler _CheckResolutionMenu(); 7235de171daSAxel Dörfler _CheckColorMenu(); 7245de171daSAxel Dörfler _CheckRefreshMenu(); 725a10cf76eSAxel Dörfler 726a10cf76eSAxel Dörfler BString string; 727a10cf76eSAxel Dörfler resolution_to_string(fSelected, string); 728a10cf76eSAxel Dörfler item = fResolutionMenu->FindItem(string.String()); 729a10cf76eSAxel Dörfler 730a10cf76eSAxel Dörfler if (item != NULL) { 731a10cf76eSAxel Dörfler if (!item->IsMarked()) 732a10cf76eSAxel Dörfler item->SetMarked(true); 733a10cf76eSAxel Dörfler } else { 734a10cf76eSAxel Dörfler // this is bad luck - if mode has been set via screen references, 735a10cf76eSAxel Dörfler // this case cannot occur; there are three possible solutions: 736a10cf76eSAxel Dörfler // 1. add a new resolution to list 737a10cf76eSAxel Dörfler // - we had to remove it as soon as a "valid" one is selected 738a10cf76eSAxel Dörfler // - we don't know which frequencies/bit depths are supported 739a10cf76eSAxel Dörfler // - as long as we haven't the GMT formula to create 740a10cf76eSAxel Dörfler // parameters for any resolution given, we cannot 741a10cf76eSAxel Dörfler // really set current mode - it's just not in the list 742a10cf76eSAxel Dörfler // 2. choose nearest resolution 743a10cf76eSAxel Dörfler // - probably a good idea, but implies coding and testing 744a10cf76eSAxel Dörfler // 3. choose lowest resolution 745a10cf76eSAxel Dörfler // - do you really think we are so lazy? yes, we are 746a10cf76eSAxel Dörfler item = fResolutionMenu->ItemAt(0); 747a10cf76eSAxel Dörfler if (item) 748a10cf76eSAxel Dörfler item->SetMarked(true); 749a10cf76eSAxel Dörfler 750a10cf76eSAxel Dörfler // okay - at least we set menu label to active resolution 751a10cf76eSAxel Dörfler fResolutionMenu->Superitem()->SetLabel(string.String()); 752a10cf76eSAxel Dörfler } 753a10cf76eSAxel Dörfler 754a10cf76eSAxel Dörfler // mark active combine mode 755a10cf76eSAxel Dörfler for (int32 i = 0; i < kCombineModeCount; i++) { 756a10cf76eSAxel Dörfler if (kCombineModes[i].mode == fSelected.combine) { 757a10cf76eSAxel Dörfler item = fCombineMenu->ItemAt(i); 758a10cf76eSAxel Dörfler if (item && !item->IsMarked()) 759a10cf76eSAxel Dörfler item->SetMarked(true); 760a10cf76eSAxel Dörfler break; 761a10cf76eSAxel Dörfler } 762a10cf76eSAxel Dörfler } 763a10cf76eSAxel Dörfler 764a10cf76eSAxel Dörfler item = fColorsMenu->ItemAt(0); 765a10cf76eSAxel Dörfler 7661fc4cb1fSAxel Dörfler for (int32 i = 0, index = 0; i < kColorSpaceCount; i++) { 7671fc4cb1fSAxel Dörfler if ((fSupportedColorSpaces & (1 << i)) == 0) 7681fc4cb1fSAxel Dörfler continue; 7691fc4cb1fSAxel Dörfler 7701fc4cb1fSAxel Dörfler if (kColorSpaces[i].space == fSelected.space) { 7711fc4cb1fSAxel Dörfler item = fColorsMenu->ItemAt(index); 772a10cf76eSAxel Dörfler break; 773a10cf76eSAxel Dörfler } 7741fc4cb1fSAxel Dörfler 7751fc4cb1fSAxel Dörfler index++; 776a10cf76eSAxel Dörfler } 777a10cf76eSAxel Dörfler 778a10cf76eSAxel Dörfler if (item && !item->IsMarked()) 779a10cf76eSAxel Dörfler item->SetMarked(true); 780a10cf76eSAxel Dörfler 7811fc4cb1fSAxel Dörfler _UpdateColorLabel(); 7825de171daSAxel Dörfler _UpdateMonitorView(); 7835de171daSAxel Dörfler _UpdateRefreshControl(); 784a10cf76eSAxel Dörfler 7855de171daSAxel Dörfler _CheckApplyEnabled(); 786a10cf76eSAxel Dörfler } 787a10cf76eSAxel Dörfler 788a10cf76eSAxel Dörfler 78912580984SAxel Dörfler /*! Reflect active mode in chosen settings */ 790a10cf76eSAxel Dörfler void 7915de171daSAxel Dörfler ScreenWindow::_UpdateActiveMode() 792a10cf76eSAxel Dörfler { 79312580984SAxel Dörfler // Usually, this function gets called after a mode 794a10cf76eSAxel Dörfler // has been set manually; still, as the graphics driver 795a10cf76eSAxel Dörfler // is free to fiddle with mode passed, we better ask 796a10cf76eSAxel Dörfler // what kind of mode we actually got 797a10cf76eSAxel Dörfler fScreenMode.Get(fActive); 798a10cf76eSAxel Dörfler fSelected = fActive; 799a10cf76eSAxel Dörfler 80012966d04SAxel Dörfler _UpdateMonitor(); 8015de171daSAxel Dörfler _UpdateControls(); 802a10cf76eSAxel Dörfler } 803a10cf76eSAxel Dörfler 804a10cf76eSAxel Dörfler 805a10cf76eSAxel Dörfler void 806b21d610eSAxel Dörfler ScreenWindow::_UpdateWorkspaceButtons() 807b21d610eSAxel Dörfler { 808b21d610eSAxel Dörfler uint32 columns; 809b21d610eSAxel Dörfler uint32 rows; 810b21d610eSAxel Dörfler BPrivate::get_workspaces_layout(&columns, &rows); 811b21d610eSAxel Dörfler 812b21d610eSAxel Dörfler char text[32]; 813b21d610eSAxel Dörfler snprintf(text, sizeof(text), "%ld", columns); 814b21d610eSAxel Dörfler fColumnsControl->SetText(text); 815b21d610eSAxel Dörfler 816b21d610eSAxel Dörfler snprintf(text, sizeof(text), "%ld", rows); 817b21d610eSAxel Dörfler fRowsControl->SetText(text); 818b21d610eSAxel Dörfler 819b21d610eSAxel Dörfler _GetColumnRowButton(true, false)->SetEnabled(columns != 1 && rows != 32); 820b21d610eSAxel Dörfler _GetColumnRowButton(true, true)->SetEnabled((columns + 1) * rows < 32); 821b21d610eSAxel Dörfler _GetColumnRowButton(false, false)->SetEnabled(rows != 1 && columns != 32); 822b21d610eSAxel Dörfler _GetColumnRowButton(false, true)->SetEnabled(columns * (rows + 1) < 32); 823b21d610eSAxel Dörfler } 824b21d610eSAxel Dörfler 825b21d610eSAxel Dörfler 826b21d610eSAxel Dörfler void 827a10cf76eSAxel Dörfler ScreenWindow::ScreenChanged(BRect frame, color_space mode) 828a10cf76eSAxel Dörfler { 829a10cf76eSAxel Dörfler // move window on screen, if necessary 830a10cf76eSAxel Dörfler if (frame.right <= Frame().right 831a10cf76eSAxel Dörfler && frame.bottom <= Frame().bottom) { 832a10cf76eSAxel Dörfler MoveTo((frame.Width() - Frame().Width()) / 2, 833a10cf76eSAxel Dörfler (frame.Height() - Frame().Height()) / 2); 834a10cf76eSAxel Dörfler } 835a10cf76eSAxel Dörfler } 836a10cf76eSAxel Dörfler 837a10cf76eSAxel Dörfler 838a10cf76eSAxel Dörfler void 839a10cf76eSAxel Dörfler ScreenWindow::WorkspaceActivated(int32 workspace, bool state) 840a10cf76eSAxel Dörfler { 841abc649b8SWaldemar Kornewald fScreenMode.GetOriginalMode(fOriginal, workspace); 8425de171daSAxel Dörfler _UpdateActiveMode(); 843a10cf76eSAxel Dörfler 8446edaa0f6SStefano Ceccherini BMessage message(UPDATE_DESKTOP_COLOR_MSG); 8456edaa0f6SStefano Ceccherini PostMessage(&message, fMonitorView); 846a10cf76eSAxel Dörfler } 847a10cf76eSAxel Dörfler 848a10cf76eSAxel Dörfler 849a10cf76eSAxel Dörfler void 850a10cf76eSAxel Dörfler ScreenWindow::MessageReceived(BMessage* message) 851a10cf76eSAxel Dörfler { 852a10cf76eSAxel Dörfler switch (message->what) { 853a10cf76eSAxel Dörfler case WORKSPACE_CHECK_MSG: 8545de171daSAxel Dörfler _CheckApplyEnabled(); 855a10cf76eSAxel Dörfler break; 856a10cf76eSAxel Dörfler 857b21d610eSAxel Dörfler case kMsgWorkspaceLayoutChanged: 858a10cf76eSAxel Dörfler { 859b21d610eSAxel Dörfler int32 deltaX = 0; 860b21d610eSAxel Dörfler int32 deltaY = 0; 861b21d610eSAxel Dörfler message->FindInt32("delta_x", &deltaX); 862b21d610eSAxel Dörfler message->FindInt32("delta_y", &deltaY); 863b21d610eSAxel Dörfler 864b21d610eSAxel Dörfler if (deltaX == 0 && deltaY == 0) 865b21d610eSAxel Dörfler break; 866b21d610eSAxel Dörfler 867b21d610eSAxel Dörfler uint32 newColumns; 868b21d610eSAxel Dörfler uint32 newRows; 869b21d610eSAxel Dörfler BPrivate::get_workspaces_layout(&newColumns, &newRows); 870b21d610eSAxel Dörfler 871b21d610eSAxel Dörfler newColumns += deltaX; 872b21d610eSAxel Dörfler newRows += deltaY; 873b21d610eSAxel Dörfler BPrivate::set_workspaces_layout(newColumns, newRows); 874b21d610eSAxel Dörfler 875b21d610eSAxel Dörfler _UpdateWorkspaceButtons(); 8765de171daSAxel Dörfler _CheckApplyEnabled(); 877b21d610eSAxel Dörfler break; 878abc649b8SWaldemar Kornewald } 879b21d610eSAxel Dörfler 880b21d610eSAxel Dörfler case kMsgWorkspaceColumnsChanged: 881b21d610eSAxel Dörfler { 882b21d610eSAxel Dörfler uint32 newColumns = strtoul(fColumnsControl->Text(), NULL, 10); 883b21d610eSAxel Dörfler 884b21d610eSAxel Dörfler uint32 rows; 885b21d610eSAxel Dörfler BPrivate::get_workspaces_layout(NULL, &rows); 886b21d610eSAxel Dörfler BPrivate::set_workspaces_layout(newColumns, rows); 887b21d610eSAxel Dörfler 888b21d610eSAxel Dörfler _UpdateWorkspaceButtons(); 889b21d610eSAxel Dörfler _CheckApplyEnabled(); 890b21d610eSAxel Dörfler break; 891b21d610eSAxel Dörfler } 892b21d610eSAxel Dörfler 893b21d610eSAxel Dörfler case kMsgWorkspaceRowsChanged: 894b21d610eSAxel Dörfler { 895b21d610eSAxel Dörfler uint32 newRows = strtoul(fRowsControl->Text(), NULL, 10); 896b21d610eSAxel Dörfler 897b21d610eSAxel Dörfler uint32 columns; 898b21d610eSAxel Dörfler BPrivate::get_workspaces_layout(&columns, NULL); 899b21d610eSAxel Dörfler BPrivate::set_workspaces_layout(columns, newRows); 900b21d610eSAxel Dörfler 901b21d610eSAxel Dörfler _UpdateWorkspaceButtons(); 902b21d610eSAxel Dörfler _CheckApplyEnabled(); 903a10cf76eSAxel Dörfler break; 904a10cf76eSAxel Dörfler } 905a10cf76eSAxel Dörfler 906a10cf76eSAxel Dörfler case POP_RESOLUTION_MSG: 907a10cf76eSAxel Dörfler { 908a10cf76eSAxel Dörfler message->FindInt32("width", &fSelected.width); 909a10cf76eSAxel Dörfler message->FindInt32("height", &fSelected.height); 910a10cf76eSAxel Dörfler 9115de171daSAxel Dörfler _CheckColorMenu(); 9125de171daSAxel Dörfler _CheckRefreshMenu(); 913a10cf76eSAxel Dörfler 9145de171daSAxel Dörfler _UpdateMonitorView(); 9155de171daSAxel Dörfler _UpdateRefreshControl(); 916a10cf76eSAxel Dörfler 9175de171daSAxel Dörfler _CheckApplyEnabled(); 918a10cf76eSAxel Dörfler break; 919a10cf76eSAxel Dörfler } 920a10cf76eSAxel Dörfler 921a10cf76eSAxel Dörfler case POP_COLORS_MSG: 922a10cf76eSAxel Dörfler { 9231fc4cb1fSAxel Dörfler int32 space; 9241fc4cb1fSAxel Dörfler if (message->FindInt32("space", &space) != B_OK) 9251fc4cb1fSAxel Dörfler break; 926a10cf76eSAxel Dörfler 9271fc4cb1fSAxel Dörfler int32 index; 9281fc4cb1fSAxel Dörfler if (message->FindInt32("index", &index) == B_OK 9291fc4cb1fSAxel Dörfler && fColorsMenu->ItemAt(index) != NULL) 9301fc4cb1fSAxel Dörfler fUserSelectedColorSpace = fColorsMenu->ItemAt(index); 9311fc4cb1fSAxel Dörfler 9321fc4cb1fSAxel Dörfler fSelected.space = (color_space)space; 9331fc4cb1fSAxel Dörfler _UpdateColorLabel(); 934a10cf76eSAxel Dörfler 9355de171daSAxel Dörfler _CheckApplyEnabled(); 936a10cf76eSAxel Dörfler break; 937a10cf76eSAxel Dörfler } 938a10cf76eSAxel Dörfler 939a10cf76eSAxel Dörfler case POP_REFRESH_MSG: 940a40498e2SWaldemar Kornewald { 941a10cf76eSAxel Dörfler message->FindFloat("refresh", &fSelected.refresh); 942c9e8f97aSAdrien Destugues fOtherRefresh->SetLabel(B_TRANSLATE("Other" B_UTF8_ELLIPSIS)); 9431fc4cb1fSAxel Dörfler // revert "Other…" label - it might have a refresh rate prefix 944a10cf76eSAxel Dörfler 9455de171daSAxel Dörfler _CheckApplyEnabled(); 946a10cf76eSAxel Dörfler break; 947a40498e2SWaldemar Kornewald } 948a10cf76eSAxel Dörfler 949a10cf76eSAxel Dörfler case POP_OTHER_REFRESH_MSG: 950a10cf76eSAxel Dörfler { 95129e8a73aSAxel Dörfler // make sure menu shows something useful 9525de171daSAxel Dörfler _UpdateRefreshControl(); 953a10cf76eSAxel Dörfler 95429e8a73aSAxel Dörfler float min = 0, max = 999; 95529e8a73aSAxel Dörfler fScreenMode.GetRefreshLimits(fSelected, min, max); 95629e8a73aSAxel Dörfler if (min < gMinRefresh) 95729e8a73aSAxel Dörfler min = gMinRefresh; 95829e8a73aSAxel Dörfler if (max > gMaxRefresh) 95929e8a73aSAxel Dörfler max = gMaxRefresh; 96029e8a73aSAxel Dörfler 96170a2b1b5SAxel Dörfler monitor_info info; 96270a2b1b5SAxel Dörfler if (fScreenMode.GetMonitorInfo(info) == B_OK) { 96370a2b1b5SAxel Dörfler min = max_c(info.min_vertical_frequency, min); 96470a2b1b5SAxel Dörfler max = min_c(info.max_vertical_frequency, max); 96570a2b1b5SAxel Dörfler } 96670a2b1b5SAxel Dörfler 967c5d10f7aSAxel Dörfler RefreshWindow *fRefreshWindow = new RefreshWindow( 96870a2b1b5SAxel Dörfler fRefreshField->ConvertToScreen(B_ORIGIN), fSelected.refresh, 96970a2b1b5SAxel Dörfler min, max); 970a10cf76eSAxel Dörfler fRefreshWindow->Show(); 971a10cf76eSAxel Dörfler break; 972a10cf76eSAxel Dörfler } 973a10cf76eSAxel Dörfler 974a10cf76eSAxel Dörfler case SET_CUSTOM_REFRESH_MSG: 975a10cf76eSAxel Dörfler { 976a10cf76eSAxel Dörfler // user pressed "done" in "Other…" refresh dialog; 977a10cf76eSAxel Dörfler // select the refresh rate chosen 978a10cf76eSAxel Dörfler message->FindFloat("refresh", &fSelected.refresh); 979a10cf76eSAxel Dörfler 9805de171daSAxel Dörfler _UpdateRefreshControl(); 9815de171daSAxel Dörfler _CheckApplyEnabled(); 982a10cf76eSAxel Dörfler break; 983a10cf76eSAxel Dörfler } 984a10cf76eSAxel Dörfler 985a10cf76eSAxel Dörfler case POP_COMBINE_DISPLAYS_MSG: 986a10cf76eSAxel Dörfler { 987a10cf76eSAxel Dörfler // new combine mode has bee chosen 988a10cf76eSAxel Dörfler int32 mode; 989a10cf76eSAxel Dörfler if (message->FindInt32("mode", &mode) == B_OK) 990a10cf76eSAxel Dörfler fSelected.combine = (combine_mode)mode; 991a10cf76eSAxel Dörfler 9925de171daSAxel Dörfler _CheckResolutionMenu(); 9935de171daSAxel Dörfler _CheckApplyEnabled(); 994a10cf76eSAxel Dörfler break; 995a10cf76eSAxel Dörfler } 996a10cf76eSAxel Dörfler 997a10cf76eSAxel Dörfler case POP_SWAP_DISPLAYS_MSG: 998a10cf76eSAxel Dörfler message->FindBool("swap", &fSelected.swap_displays); 9995de171daSAxel Dörfler _CheckApplyEnabled(); 1000a10cf76eSAxel Dörfler break; 1001a10cf76eSAxel Dörfler 1002a10cf76eSAxel Dörfler case POP_USE_LAPTOP_PANEL_MSG: 1003a10cf76eSAxel Dörfler message->FindBool("use", &fSelected.use_laptop_panel); 10045de171daSAxel Dörfler _CheckApplyEnabled(); 1005a10cf76eSAxel Dörfler break; 1006a10cf76eSAxel Dörfler 1007a10cf76eSAxel Dörfler case POP_TV_STANDARD_MSG: 1008a10cf76eSAxel Dörfler message->FindInt32("tv_standard", (int32 *)&fSelected.tv_standard); 10095de171daSAxel Dörfler _CheckApplyEnabled(); 1010a10cf76eSAxel Dörfler break; 1011a10cf76eSAxel Dörfler 1012df3f5bacSStephan Aßmus case BUTTON_LAUNCH_BACKGROUNDS_MSG: 10136f095d6aSRyan Leavengood if (be_roster->Launch(kBackgroundsSignature) == B_ALREADY_RUNNING) { 10146f095d6aSRyan Leavengood app_info info; 10156f095d6aSRyan Leavengood be_roster->GetAppInfo(kBackgroundsSignature, &info); 10166f095d6aSRyan Leavengood be_roster->ActivateApp(info.team); 10176f095d6aSRyan Leavengood } 1018df3f5bacSStephan Aßmus break; 1019df3f5bacSStephan Aßmus 1020a10cf76eSAxel Dörfler case BUTTON_DEFAULTS_MSG: 1021a10cf76eSAxel Dörfler { 10224be51fe3SWaldemar Kornewald // TODO: get preferred settings of screen 1023a10cf76eSAxel Dörfler fSelected.width = 640; 1024a10cf76eSAxel Dörfler fSelected.height = 480; 1025a10cf76eSAxel Dörfler fSelected.space = B_CMAP8; 1026a10cf76eSAxel Dörfler fSelected.refresh = 60.0; 1027a10cf76eSAxel Dörfler fSelected.combine = kCombineDisable; 1028a10cf76eSAxel Dörfler fSelected.swap_displays = false; 1029a10cf76eSAxel Dörfler fSelected.use_laptop_panel = false; 1030a10cf76eSAxel Dörfler fSelected.tv_standard = 0; 1031a10cf76eSAxel Dörfler 1032b21d610eSAxel Dörfler // TODO: workspace defaults 1033abc649b8SWaldemar Kornewald 10345de171daSAxel Dörfler _UpdateControls(); 1035a10cf76eSAxel Dörfler break; 1036a10cf76eSAxel Dörfler } 1037a10cf76eSAxel Dörfler 103810e9b12fSWaldemar Kornewald case BUTTON_UNDO_MSG: 103961c5c89bSAxel Dörfler fUndoScreenMode.Revert(); 10405de171daSAxel Dörfler _UpdateActiveMode(); 1041abc649b8SWaldemar Kornewald break; 1042abc649b8SWaldemar Kornewald 1043abc649b8SWaldemar Kornewald case BUTTON_REVERT_MSG: 1044abc649b8SWaldemar Kornewald { 1045abc649b8SWaldemar Kornewald fModified = false; 1046199893c3SAxel Dörfler fBootWorkspaceApplied = false; 1047abc649b8SWaldemar Kornewald 1048b21d610eSAxel Dörfler // ScreenMode::Revert() assumes that we first set the correct 1049b21d610eSAxel Dörfler // number of workspaces 1050b21d610eSAxel Dörfler 1051b21d610eSAxel Dörfler BPrivate::set_workspaces_layout(fOriginalWorkspacesColumns, 1052b21d610eSAxel Dörfler fOriginalWorkspacesRows); 1053b21d610eSAxel Dörfler _UpdateWorkspaceButtons(); 1054b21d610eSAxel Dörfler 1055a10cf76eSAxel Dörfler fScreenMode.Revert(); 10565de171daSAxel Dörfler _UpdateActiveMode(); 1057a10cf76eSAxel Dörfler break; 1058abc649b8SWaldemar Kornewald } 1059a10cf76eSAxel Dörfler 1060a10cf76eSAxel Dörfler case BUTTON_APPLY_MSG: 10615de171daSAxel Dörfler _Apply(); 1062a10cf76eSAxel Dörfler break; 1063a10cf76eSAxel Dörfler 1064abc649b8SWaldemar Kornewald case MAKE_INITIAL_MSG: 1065abc649b8SWaldemar Kornewald // user pressed "keep" in confirmation dialog 1066abc649b8SWaldemar Kornewald fModified = true; 10675de171daSAxel Dörfler _UpdateActiveMode(); 1068a10cf76eSAxel Dörfler break; 1069a10cf76eSAxel Dörfler 1070a10cf76eSAxel Dörfler default: 1071a10cf76eSAxel Dörfler BWindow::MessageReceived(message); 1072a10cf76eSAxel Dörfler break; 1073a10cf76eSAxel Dörfler } 1074a10cf76eSAxel Dörfler } 1075a10cf76eSAxel Dörfler 1076a10cf76eSAxel Dörfler 107712580984SAxel Dörfler status_t 107812580984SAxel Dörfler ScreenWindow::_WriteVesaModeFile(const screen_mode& mode) const 107912580984SAxel Dörfler { 108012580984SAxel Dörfler BPath path; 108112580984SAxel Dörfler status_t status = find_directory(B_USER_SETTINGS_DIRECTORY, &path, true); 108212580984SAxel Dörfler if (status < B_OK) 108312580984SAxel Dörfler return status; 108412580984SAxel Dörfler 108512580984SAxel Dörfler path.Append("kernel/drivers"); 108612580984SAxel Dörfler status = create_directory(path.Path(), 0755); 108712580984SAxel Dörfler if (status < B_OK) 108812580984SAxel Dörfler return status; 108912580984SAxel Dörfler 109012580984SAxel Dörfler path.Append("vesa"); 109112580984SAxel Dörfler BFile file; 109212580984SAxel Dörfler status = file.SetTo(path.Path(), B_CREATE_FILE | B_WRITE_ONLY | B_ERASE_FILE); 109312580984SAxel Dörfler if (status < B_OK) 109412580984SAxel Dörfler return status; 109512580984SAxel Dörfler 109612580984SAxel Dörfler char buffer[256]; 109712580984SAxel Dörfler snprintf(buffer, sizeof(buffer), "mode %ld %ld %ld\n", 109812580984SAxel Dörfler mode.width, mode.height, mode.BitsPerPixel()); 109912580984SAxel Dörfler 110012580984SAxel Dörfler ssize_t bytesWritten = file.Write(buffer, strlen(buffer)); 110112580984SAxel Dörfler if (bytesWritten < B_OK) 110212580984SAxel Dörfler return bytesWritten; 110312580984SAxel Dörfler 110412580984SAxel Dörfler return B_OK; 110512580984SAxel Dörfler } 110612580984SAxel Dörfler 110712580984SAxel Dörfler 1108b21d610eSAxel Dörfler BButton* 1109b21d610eSAxel Dörfler ScreenWindow::_CreateColumnRowButton(bool columns, bool plus) 1110b21d610eSAxel Dörfler { 1111b21d610eSAxel Dörfler BMessage* message = new BMessage(kMsgWorkspaceLayoutChanged); 1112b21d610eSAxel Dörfler message->AddInt32("delta_x", columns ? (plus ? 1 : -1) : 0); 1113b21d610eSAxel Dörfler message->AddInt32("delta_y", !columns ? (plus ? 1 : -1) : 0); 1114b21d610eSAxel Dörfler 1115b21d610eSAxel Dörfler BButton* button = new BButton(plus ? "+" : "-", message); 1116b21d610eSAxel Dörfler button->SetFontSize(be_plain_font->Size() * 0.9); 1117b21d610eSAxel Dörfler 1118b21d610eSAxel Dörfler BSize size = button->MinSize(); 1119b21d610eSAxel Dörfler size.width = button->StringWidth("+") + 16; 1120b21d610eSAxel Dörfler button->SetExplicitMinSize(size); 1121b21d610eSAxel Dörfler button->SetExplicitMaxSize(size); 1122b21d610eSAxel Dörfler 1123b21d610eSAxel Dörfler fWorkspacesButtons[(columns ? 0 : 2) + (plus ? 1 : 0)] = button; 1124b21d610eSAxel Dörfler return button; 1125b21d610eSAxel Dörfler } 1126b21d610eSAxel Dörfler 1127b21d610eSAxel Dörfler 1128b21d610eSAxel Dörfler BButton* 1129b21d610eSAxel Dörfler ScreenWindow::_GetColumnRowButton(bool columns, bool plus) 1130b21d610eSAxel Dörfler { 1131b21d610eSAxel Dörfler return fWorkspacesButtons[(columns ? 0 : 2) + (plus ? 1 : 0)]; 1132b21d610eSAxel Dörfler } 1133b21d610eSAxel Dörfler 1134b21d610eSAxel Dörfler 1135a10cf76eSAxel Dörfler void 11361fc4cb1fSAxel Dörfler ScreenWindow::_BuildSupportedColorSpaces() 11371fc4cb1fSAxel Dörfler { 11381fc4cb1fSAxel Dörfler fSupportedColorSpaces = 0; 11391fc4cb1fSAxel Dörfler 11401fc4cb1fSAxel Dörfler for (int32 i = 0; i < kColorSpaceCount; i++) { 11411fc4cb1fSAxel Dörfler for (int32 j = 0; j < fScreenMode.CountModes(); j++) { 11421fc4cb1fSAxel Dörfler if (fScreenMode.ModeAt(j).space == kColorSpaces[i].space) { 11431fc4cb1fSAxel Dörfler fSupportedColorSpaces |= 1 << i; 11441fc4cb1fSAxel Dörfler break; 11451fc4cb1fSAxel Dörfler } 11461fc4cb1fSAxel Dörfler } 11471fc4cb1fSAxel Dörfler } 11481fc4cb1fSAxel Dörfler } 11491fc4cb1fSAxel Dörfler 11501fc4cb1fSAxel Dörfler 11511fc4cb1fSAxel Dörfler void 11525de171daSAxel Dörfler ScreenWindow::_CheckApplyEnabled() 1153a10cf76eSAxel Dörfler { 115427c43a2dSRene Gollent fApplyButton->SetEnabled(fSelected != fActive 115527c43a2dSRene Gollent || fAllWorkspacesItem->IsMarked()); 1156b21d610eSAxel Dörfler 1157b21d610eSAxel Dörfler uint32 columns; 1158b21d610eSAxel Dörfler uint32 rows; 1159b21d610eSAxel Dörfler BPrivate::get_workspaces_layout(&columns, &rows); 1160b21d610eSAxel Dörfler 1161b21d610eSAxel Dörfler fRevertButton->SetEnabled(columns != fOriginalWorkspacesColumns 1162b21d610eSAxel Dörfler || rows != fOriginalWorkspacesRows 11635de171daSAxel Dörfler || fSelected != fOriginal); 1164a10cf76eSAxel Dörfler } 1165a10cf76eSAxel Dörfler 1166a10cf76eSAxel Dörfler 1167a10cf76eSAxel Dörfler void 11685de171daSAxel Dörfler ScreenWindow::_UpdateOriginal() 1169abc649b8SWaldemar Kornewald { 1170b21d610eSAxel Dörfler BPrivate::get_workspaces_layout(&fOriginalWorkspacesColumns, 1171b21d610eSAxel Dörfler &fOriginalWorkspacesRows); 1172b21d610eSAxel Dörfler 1173abc649b8SWaldemar Kornewald fScreenMode.Get(fOriginal); 1174abc649b8SWaldemar Kornewald fScreenMode.UpdateOriginalModes(); 1175abc649b8SWaldemar Kornewald } 1176abc649b8SWaldemar Kornewald 1177abc649b8SWaldemar Kornewald 1178abc649b8SWaldemar Kornewald void 117912966d04SAxel Dörfler ScreenWindow::_UpdateMonitor() 118012966d04SAxel Dörfler { 118112966d04SAxel Dörfler monitor_info info; 118212966d04SAxel Dörfler float diagonalInches; 118312966d04SAxel Dörfler status_t status = fScreenMode.GetMonitorInfo(info, &diagonalInches); 118455030977SAxel Dörfler if (status == B_OK) { 11851a8af605SAxel Dörfler char text[512]; 118666ab1666SAxel Dörfler snprintf(text, sizeof(text), "%s%s%s %g\"", info.vendor, 118766ab1666SAxel Dörfler info.name[0] ? " " : "", info.name, diagonalInches); 118812966d04SAxel Dörfler 118912966d04SAxel Dörfler fMonitorInfo->SetText(text); 119012966d04SAxel Dörfler 119112966d04SAxel Dörfler if (fMonitorInfo->IsHidden()) 119212966d04SAxel Dörfler fMonitorInfo->Show(); 119355030977SAxel Dörfler } else { 119455030977SAxel Dörfler if (!fMonitorInfo->IsHidden()) 119555030977SAxel Dörfler fMonitorInfo->Hide(); 119655030977SAxel Dörfler } 1197af8f9c31SAxel Dörfler 119855030977SAxel Dörfler char text[512]; 11991a8af605SAxel Dörfler size_t length = 0; 12001a8af605SAxel Dörfler text[0] = 0; 12011a8af605SAxel Dörfler 120255030977SAxel Dörfler if (status == B_OK) { 1203af8f9c31SAxel Dörfler if (info.min_horizontal_frequency != 0 1204af8f9c31SAxel Dörfler && info.min_vertical_frequency != 0 1205af8f9c31SAxel Dörfler && info.max_pixel_clock != 0) { 12061a8af605SAxel Dörfler length = snprintf(text, sizeof(text), 1207c9e8f97aSAdrien Destugues B_TRANSLATE("Horizonal frequency:\t%lu - %lu kHz\n" 12089c1a9b92SAdrien Destugues "Vertical frequency:\t%lu - %lu Hz\n\n" 1209c9e8f97aSAdrien Destugues "Maximum pixel clock:\t%g MHz"), 12101a8af605SAxel Dörfler info.min_horizontal_frequency, info.max_horizontal_frequency, 12111a8af605SAxel Dörfler info.min_vertical_frequency, info.max_vertical_frequency, 12121a8af605SAxel Dörfler info.max_pixel_clock / 1000.0); 1213af8f9c31SAxel Dörfler } 12141a8af605SAxel Dörfler if (info.serial_number[0] && length < sizeof(text)) { 12151a8af605SAxel Dörfler length += snprintf(text + length, sizeof(text) - length, 1216c9e8f97aSAdrien Destugues B_TRANSLATE("%sSerial no.: %s"), length ? "\n\n" : "", 12171a8af605SAxel Dörfler info.serial_number); 12181a8af605SAxel Dörfler if (info.produced.week != 0 && info.produced.year != 0 12191a8af605SAxel Dörfler && length < sizeof(text)) { 12201a8af605SAxel Dörfler length += snprintf(text + length, sizeof(text) - length, 12211a8af605SAxel Dörfler " (%u/%u)", info.produced.week, info.produced.year); 12221a8af605SAxel Dörfler } 12231a8af605SAxel Dörfler } 122455030977SAxel Dörfler } 122561c5c89bSAxel Dörfler 122661c5c89bSAxel Dörfler // Add info about the graphics device 122761c5c89bSAxel Dörfler 122861c5c89bSAxel Dörfler accelerant_device_info deviceInfo; 122961c5c89bSAxel Dörfler if (fScreenMode.GetDeviceInfo(deviceInfo) == B_OK 123061c5c89bSAxel Dörfler && length < sizeof(text)) { 123161c5c89bSAxel Dörfler if (deviceInfo.name[0] && deviceInfo.chipset[0]) { 123261c5c89bSAxel Dörfler length += snprintf(text + length, sizeof(text) - length, 123361c5c89bSAxel Dörfler "%s%s (%s)", length != 0 ? "\n\n" : "", deviceInfo.name, 123461c5c89bSAxel Dörfler deviceInfo.chipset); 123561c5c89bSAxel Dörfler } else if (deviceInfo.name[0] || deviceInfo.chipset[0]) { 123661c5c89bSAxel Dörfler length += snprintf(text + length, sizeof(text) - length, 123761c5c89bSAxel Dörfler "%s%s", length != 0 ? "\n\n" : "", deviceInfo.name[0] 123861c5c89bSAxel Dörfler ? deviceInfo.name : deviceInfo.chipset); 123961c5c89bSAxel Dörfler } 124061c5c89bSAxel Dörfler } 124161c5c89bSAxel Dörfler 12421a8af605SAxel Dörfler if (text[0]) 12431a8af605SAxel Dörfler fMonitorView->SetToolTip(text); 124412966d04SAxel Dörfler } 124512966d04SAxel Dörfler 124612966d04SAxel Dörfler 124712966d04SAxel Dörfler void 12481fc4cb1fSAxel Dörfler ScreenWindow::_UpdateColorLabel() 12491fc4cb1fSAxel Dörfler { 12501fc4cb1fSAxel Dörfler BString string; 1251551c9f15SSiarzhuk Zharski string << fSelected.BitsPerPixel() << " " << B_TRANSLATE("bits/pixel"); 12521fc4cb1fSAxel Dörfler fColorsMenu->Superitem()->SetLabel(string.String()); 12531fc4cb1fSAxel Dörfler } 12541fc4cb1fSAxel Dörfler 12551fc4cb1fSAxel Dörfler 12561fc4cb1fSAxel Dörfler void 12575de171daSAxel Dörfler ScreenWindow::_Apply() 1258a10cf76eSAxel Dörfler { 1259abc649b8SWaldemar Kornewald // make checkpoint, so we can undo these changes 126061c5c89bSAxel Dörfler fUndoScreenMode.UpdateOriginalModes(); 126161c5c89bSAxel Dörfler 126207184a9eSAxel Dörfler status_t status = fScreenMode.Set(fSelected); 126307184a9eSAxel Dörfler if (status == B_OK) { 1264abc649b8SWaldemar Kornewald // use the mode that has eventually been set and 1265abc649b8SWaldemar Kornewald // thus we know to be working; it can differ from 1266abc649b8SWaldemar Kornewald // the mode selected by user due to hardware limitation 1267abc649b8SWaldemar Kornewald display_mode newMode; 1268abc649b8SWaldemar Kornewald BScreen screen(this); 1269abc649b8SWaldemar Kornewald screen.GetMode(&newMode); 1270abc649b8SWaldemar Kornewald 1271abc649b8SWaldemar Kornewald if (fAllWorkspacesItem->IsMarked()) { 1272abc649b8SWaldemar Kornewald int32 originatingWorkspace = current_workspace(); 1273abc649b8SWaldemar Kornewald for (int32 i = 0; i < count_workspaces(); i++) { 1274abc649b8SWaldemar Kornewald if (i != originatingWorkspace) 1275abc649b8SWaldemar Kornewald screen.SetMode(i, &newMode, true); 1276abc649b8SWaldemar Kornewald } 1277199893c3SAxel Dörfler fBootWorkspaceApplied = true; 1278199893c3SAxel Dörfler } else { 1279199893c3SAxel Dörfler if (current_workspace() == 0) 1280199893c3SAxel Dörfler fBootWorkspaceApplied = true; 1281abc649b8SWaldemar Kornewald } 1282abc649b8SWaldemar Kornewald 1283a10cf76eSAxel Dörfler fActive = fSelected; 1284a10cf76eSAxel Dörfler 1285abc649b8SWaldemar Kornewald // TODO: only show alert when this is an unknown mode 1286a10cf76eSAxel Dörfler BWindow* window = new AlertWindow(this); 1287a10cf76eSAxel Dörfler window->Show(); 128807184a9eSAxel Dörfler } else { 128907184a9eSAxel Dörfler char message[256]; 129007184a9eSAxel Dörfler snprintf(message, sizeof(message), 1291c9e8f97aSAdrien Destugues B_TRANSLATE("The screen mode could not be set:\n\t%s\n"), 1292c9e8f97aSAdrien Destugues screen_errors(status)); 1293551c9f15SSiarzhuk Zharski BAlert* alert = new BAlert(B_TRANSLATE("Warning"), message, 1294c9e8f97aSAdrien Destugues B_TRANSLATE("OK"), NULL, NULL, 129507184a9eSAxel Dörfler B_WIDTH_AS_USUAL, B_WARNING_ALERT); 129607184a9eSAxel Dörfler alert->Go(); 1297a10cf76eSAxel Dörfler } 129807184a9eSAxel Dörfler } 129907184a9eSAxel Dörfler 1300