1a10cf76eSAxel Dörfler /* 2*10dfe897SAxel Dörfler * Copyright 2001-2011, Haiku. 3a10cf76eSAxel Dörfler * Distributed under the terms of the MIT License. 4a10cf76eSAxel Dörfler * 5a10cf76eSAxel Dörfler * Authors: 6a10cf76eSAxel Dörfler * Rafael Romo 7a10cf76eSAxel Dörfler * Stefano Ceccherini (burton666@libero.it) 8a10cf76eSAxel Dörfler * Andrew Bachmann 9a10cf76eSAxel Dörfler * Thomas Kurschel 10a10cf76eSAxel Dörfler * Axel Dörfler, axeld@pinc-software.de 11df3f5bacSStephan Aßmus * Stephan Aßmus <superstippi@gmx.de> 12b72c4836SAlexandre Deckner * Alexandre Deckner, alex@zappotek.com 13a10cf76eSAxel Dörfler */ 14a10cf76eSAxel Dörfler 15a10cf76eSAxel Dörfler 16b21d610eSAxel Dörfler #include "ScreenWindow.h" 17b21d610eSAxel Dörfler 18b21d610eSAxel Dörfler #include <stdio.h> 19b21d610eSAxel Dörfler #include <stdlib.h> 20b21d610eSAxel Dörfler #include <string.h> 21b21d610eSAxel Dörfler 22b21d610eSAxel Dörfler #include <Alert.h> 23b21d610eSAxel Dörfler #include <Application.h> 24b21d610eSAxel Dörfler #include <Box.h> 25b21d610eSAxel Dörfler #include <Button.h> 26c9e8f97aSAdrien Destugues #include <Catalog.h> 27b21d610eSAxel Dörfler #include <Directory.h> 28b21d610eSAxel Dörfler #include <File.h> 29b21d610eSAxel Dörfler #include <FindDirectory.h> 30b21d610eSAxel Dörfler #include <InterfaceDefs.h> 31b21d610eSAxel Dörfler #include <LayoutBuilder.h> 32b21d610eSAxel Dörfler #include <MenuBar.h> 33b21d610eSAxel Dörfler #include <MenuItem.h> 34b21d610eSAxel Dörfler #include <MenuField.h> 35b21d610eSAxel Dörfler #include <Messenger.h> 36b21d610eSAxel Dörfler #include <Path.h> 37b21d610eSAxel Dörfler #include <PopUpMenu.h> 38b21d610eSAxel Dörfler #include <Screen.h> 39b21d610eSAxel Dörfler #include <String.h> 40b21d610eSAxel Dörfler #include <StringView.h> 41b21d610eSAxel Dörfler #include <Roster.h> 42b21d610eSAxel Dörfler #include <Window.h> 43b21d610eSAxel Dörfler 44b21d610eSAxel Dörfler #include <InterfacePrivate.h> 45b21d610eSAxel Dörfler 46a10cf76eSAxel Dörfler #include "AlertWindow.h" 47a10cf76eSAxel Dörfler #include "Constants.h" 48a10cf76eSAxel Dörfler #include "RefreshWindow.h" 49a10cf76eSAxel Dörfler #include "MonitorView.h" 50a10cf76eSAxel Dörfler #include "ScreenSettings.h" 51a10cf76eSAxel Dörfler #include "Utility.h" 52a10cf76eSAxel Dörfler 53a10cf76eSAxel Dörfler /* Note, this headers defines a *private* interface to the Radeon accelerant. 54a10cf76eSAxel Dörfler * It's a solution that works with the current BeOS interface that Haiku 55a10cf76eSAxel Dörfler * adopted. 56a10cf76eSAxel Dörfler * However, it's not a nice and clean solution. Don't use this header in any 57a10cf76eSAxel Dörfler * application if you can avoid it. No other driver is using this, or should 58a10cf76eSAxel Dörfler * be using this. 59a10cf76eSAxel Dörfler * It will be replaced as soon as we introduce an updated accelerant interface 60a10cf76eSAxel Dörfler * which may even happen before R1 hits the streets. 61a10cf76eSAxel Dörfler */ 62a10cf76eSAxel Dörfler #include "multimon.h" // the usual: DANGER WILL, ROBINSON! 63a10cf76eSAxel Dörfler 64a10cf76eSAxel Dörfler 65c9e8f97aSAdrien Destugues #undef B_TRANSLATE_CONTEXT 66c9e8f97aSAdrien Destugues #define B_TRANSLATE_CONTEXT "Screen" 67c9e8f97aSAdrien Destugues 68c9e8f97aSAdrien Destugues 6975c92c56SRyan Leavengood const char* kBackgroundsSignature = "application/x-vnd.Haiku-Backgrounds"; 70c5d80d47SAxel Dörfler 71a10cf76eSAxel Dörfler // list of officially supported colour spaces 72a10cf76eSAxel Dörfler static const struct { 73a10cf76eSAxel Dörfler color_space space; 74a10cf76eSAxel Dörfler int32 bits_per_pixel; 75a10cf76eSAxel Dörfler const char* label; 76a10cf76eSAxel Dörfler } kColorSpaces[] = { 7726747978SAdrien Destugues { B_CMAP8, 8, B_TRANSLATE("8 bits/pixel, 256 colors") }, 78c9e8f97aSAdrien Destugues { B_RGB15, 15, B_TRANSLATE("15 bits/pixel, 32768 colors") }, 79c9e8f97aSAdrien Destugues { B_RGB16, 16, B_TRANSLATE("16 bits/pixel, 65536 colors") }, 80c9e8f97aSAdrien Destugues { B_RGB24, 24, B_TRANSLATE("24 bits/pixel, 16 Million colors") }, 81c9e8f97aSAdrien Destugues { B_RGB32, 32, B_TRANSLATE("32 bits/pixel, 16 Million colors") } 82a10cf76eSAxel Dörfler }; 83b21d610eSAxel Dörfler static const int32 kColorSpaceCount 84b21d610eSAxel Dörfler = sizeof(kColorSpaces) / sizeof(kColorSpaces[0]); 85a10cf76eSAxel Dörfler 86a10cf76eSAxel Dörfler // list of standard refresh rates 87a796facfSAxel Dörfler static const int32 kRefreshRates[] = { 60, 70, 72, 75, 80, 85, 95, 100 }; 88b21d610eSAxel Dörfler static const int32 kRefreshRateCount 89b21d610eSAxel Dörfler = sizeof(kRefreshRates) / sizeof(kRefreshRates[0]); 90a10cf76eSAxel Dörfler 91a10cf76eSAxel Dörfler // list of combine modes 92a10cf76eSAxel Dörfler static const struct { 93a10cf76eSAxel Dörfler combine_mode mode; 94a10cf76eSAxel Dörfler const char *name; 95a10cf76eSAxel Dörfler } kCombineModes[] = { 96c9e8f97aSAdrien Destugues { kCombineDisable, B_TRANSLATE("disable") }, 97c9e8f97aSAdrien Destugues { kCombineHorizontally, B_TRANSLATE("horizontally") }, 98c9e8f97aSAdrien Destugues { kCombineVertically, B_TRANSLATE("vertically") } 99a10cf76eSAxel Dörfler }; 100b21d610eSAxel Dörfler static const int32 kCombineModeCount 101b21d610eSAxel Dörfler = sizeof(kCombineModes) / sizeof(kCombineModes[0]); 10229e8a73aSAxel Dörfler 103a10cf76eSAxel Dörfler 104a10cf76eSAxel Dörfler static BString 105a10cf76eSAxel Dörfler tv_standard_to_string(uint32 mode) 106a10cf76eSAxel Dörfler { 107a10cf76eSAxel Dörfler switch (mode) { 108a10cf76eSAxel Dörfler case 0: return "disabled"; 109a10cf76eSAxel Dörfler case 1: return "NTSC"; 110a10cf76eSAxel Dörfler case 2: return "NTSC Japan"; 111a10cf76eSAxel Dörfler case 3: return "PAL BDGHI"; 112a10cf76eSAxel Dörfler case 4: return "PAL M"; 113a10cf76eSAxel Dörfler case 5: return "PAL N"; 114a10cf76eSAxel Dörfler case 6: return "SECAM"; 115a10cf76eSAxel Dörfler case 101: return "NTSC 443"; 116a10cf76eSAxel Dörfler case 102: return "PAL 60"; 117a10cf76eSAxel Dörfler case 103: return "PAL NC"; 118a10cf76eSAxel Dörfler default: 119a10cf76eSAxel Dörfler { 120a10cf76eSAxel Dörfler BString name; 121a10cf76eSAxel Dörfler name << "??? (" << mode << ")"; 122a10cf76eSAxel Dörfler 123a10cf76eSAxel Dörfler return name; 124a10cf76eSAxel Dörfler } 125a10cf76eSAxel Dörfler } 126a10cf76eSAxel Dörfler } 127a10cf76eSAxel Dörfler 128a10cf76eSAxel Dörfler 129a10cf76eSAxel Dörfler static void 130a10cf76eSAxel Dörfler resolution_to_string(screen_mode& mode, BString &string) 131a10cf76eSAxel Dörfler { 132a10cf76eSAxel Dörfler string << mode.width << " x " << mode.height; 133a10cf76eSAxel Dörfler } 134a10cf76eSAxel Dörfler 135a10cf76eSAxel Dörfler 136a10cf76eSAxel Dörfler static void 137a10cf76eSAxel Dörfler refresh_rate_to_string(float refresh, BString &string, 138a10cf76eSAxel Dörfler bool appendUnit = true, bool alwaysWithFraction = false) 139a10cf76eSAxel Dörfler { 1408bf23e3cSAxel Dörfler snprintf(string.LockBuffer(32), 32, "%.*g", refresh >= 100.0 ? 4 : 3, 1418bf23e3cSAxel Dörfler refresh); 142a10cf76eSAxel Dörfler string.UnlockBuffer(); 143a10cf76eSAxel Dörfler 144a10cf76eSAxel Dörfler if (appendUnit) 145551c9f15SSiarzhuk Zharski string << " " << B_TRANSLATE("Hz"); 146a10cf76eSAxel Dörfler } 147a10cf76eSAxel Dörfler 148a10cf76eSAxel Dörfler 14907184a9eSAxel Dörfler static const char* 15007184a9eSAxel Dörfler screen_errors(status_t status) 15107184a9eSAxel Dörfler { 15207184a9eSAxel Dörfler switch (status) { 15307184a9eSAxel Dörfler case B_ENTRY_NOT_FOUND: 154c9e8f97aSAdrien Destugues return B_TRANSLATE("Unknown mode"); 15507184a9eSAxel Dörfler // TODO: add more? 15607184a9eSAxel Dörfler 15707184a9eSAxel Dörfler default: 15807184a9eSAxel Dörfler return strerror(status); 15907184a9eSAxel Dörfler } 16007184a9eSAxel Dörfler } 16107184a9eSAxel Dörfler 16229e8a73aSAxel Dörfler 1633dfd20c0SStephan Aßmus // #pragma mark - 1643dfd20c0SStephan Aßmus 1653dfd20c0SStephan Aßmus 1665a78744bSAxel Dörfler ScreenWindow::ScreenWindow(ScreenSettings* settings) 167b21d610eSAxel Dörfler : 168560ff447SJonas Sundström BWindow(settings->WindowFrame(), B_TRANSLATE_SYSTEM_NAME("Screen"), 169d374a272SJonas Sundström B_TITLED_WINDOW, B_NOT_ZOOMABLE | B_AUTO_UPDATE_SIZE_LIMITS, 170b21d610eSAxel Dörfler B_ALL_WORKSPACES), 171199893c3SAxel Dörfler fBootWorkspaceApplied(false), 172a10cf76eSAxel Dörfler fScreenMode(this), 17361c5c89bSAxel Dörfler fUndoScreenMode(this), 174abc649b8SWaldemar Kornewald fModified(false) 175a10cf76eSAxel Dörfler { 176a10cf76eSAxel Dörfler BScreen screen(this); 177a10cf76eSAxel Dörfler 17812580984SAxel Dörfler accelerant_device_info info; 179d1516993SAxel Dörfler if (screen.GetDeviceInfo(&info) == B_OK 180d1516993SAxel Dörfler && !strcasecmp(info.chipset, "VESA")) 18112580984SAxel Dörfler fIsVesa = true; 18212580984SAxel Dörfler 1835de171daSAxel Dörfler _UpdateOriginal(); 1841fc4cb1fSAxel Dörfler _BuildSupportedColorSpaces(); 185a10cf76eSAxel Dörfler fActive = fSelected = fOriginal; 186a10cf76eSAxel Dörfler 1875a78744bSAxel Dörfler fSettings = settings; 1885a78744bSAxel Dörfler 1895a78744bSAxel Dörfler // we need the "Current Workspace" first to get its height 1905a78744bSAxel Dörfler 191c9e8f97aSAdrien Destugues BPopUpMenu *popUpMenu = new BPopUpMenu(B_TRANSLATE("Current workspace"), 192c9e8f97aSAdrien Destugues true, true); 193c9e8f97aSAdrien Destugues fAllWorkspacesItem = new BMenuItem(B_TRANSLATE("All workspaces"), 194d1516993SAxel Dörfler new BMessage(WORKSPACE_CHECK_MSG)); 1955a78744bSAxel Dörfler popUpMenu->AddItem(fAllWorkspacesItem); 196c9e8f97aSAdrien Destugues BMenuItem *item = new BMenuItem(B_TRANSLATE("Current workspace"), 197d1516993SAxel Dörfler new BMessage(WORKSPACE_CHECK_MSG)); 198b72c4836SAlexandre Deckner 1995a78744bSAxel Dörfler popUpMenu->AddItem(item); 20027c43a2dSRene Gollent fAllWorkspacesItem->SetMarked(true); 2015a78744bSAxel Dörfler 202b21d610eSAxel Dörfler BMenuField* workspaceMenuField = new BMenuField("WorkspaceMenu", NULL, 203*10dfe897SAxel Dörfler popUpMenu); 2045a78744bSAxel Dörfler workspaceMenuField->ResizeToPreferred(); 205a10cf76eSAxel Dörfler 206a10cf76eSAxel Dörfler // box on the left with workspace count and monitor view 207a10cf76eSAxel Dörfler 208b21d610eSAxel Dörfler BBox* screenBox = new BBox("screen box"); 2098bf23e3cSAxel Dörfler BGroupLayout* layout = new BGroupLayout(B_VERTICAL, 5.0); 210b21d610eSAxel Dörfler layout->SetInsets(10, 10, 10, 10); 211b21d610eSAxel Dörfler screenBox->SetLayout(layout); 212a10cf76eSAxel Dörfler 21312966d04SAxel Dörfler fMonitorInfo = new BStringView("monitor info", ""); 21412966d04SAxel Dörfler screenBox->AddChild(fMonitorInfo); 21512966d04SAxel Dörfler 216c9e8f97aSAdrien Destugues fMonitorView = new MonitorView(BRect(0.0, 0.0, 80.0, 80.0), 217551c9f15SSiarzhuk Zharski "monitor", screen.Frame().IntegerWidth() + 1, 218c9e8f97aSAdrien Destugues screen.Frame().IntegerHeight() + 1); 219b21d610eSAxel Dörfler screenBox->AddChild(fMonitorView); 2205a78744bSAxel Dörfler 221c9e8f97aSAdrien Destugues fColumnsControl = new BTextControl(B_TRANSLATE("Columns:"), "0", 222b21d610eSAxel Dörfler new BMessage(kMsgWorkspaceColumnsChanged)); 223c9e8f97aSAdrien Destugues fRowsControl = new BTextControl(B_TRANSLATE("Rows:"), "0", 224b21d610eSAxel Dörfler new BMessage(kMsgWorkspaceRowsChanged)); 225b21d610eSAxel Dörfler 226b21d610eSAxel Dörfler screenBox->AddChild(BLayoutBuilder::Grid<>(5.0, 5.0) 227c9e8f97aSAdrien Destugues .Add(new BStringView("", B_TRANSLATE("Workspaces")), 0, 0, 3) 228b21d610eSAxel Dörfler .AddTextControl(fColumnsControl, 0, 1, B_ALIGN_RIGHT) 229b21d610eSAxel Dörfler .AddGroup(B_HORIZONTAL, 0, 2, 1) 230b21d610eSAxel Dörfler .Add(_CreateColumnRowButton(true, false)) 231b21d610eSAxel Dörfler .Add(_CreateColumnRowButton(true, true)) 232b21d610eSAxel Dörfler .End() 233b21d610eSAxel Dörfler .AddTextControl(fRowsControl, 0, 2, B_ALIGN_RIGHT) 234b21d610eSAxel Dörfler .AddGroup(B_HORIZONTAL, 0, 2, 2) 235b21d610eSAxel Dörfler .Add(_CreateColumnRowButton(false, false)) 236b21d610eSAxel Dörfler .Add(_CreateColumnRowButton(false, true)) 23725fd5c7bSAlex Wilson .End() 23825fd5c7bSAlex Wilson .View()); 239b21d610eSAxel Dörfler 240b21d610eSAxel Dörfler fBackgroundsButton = new BButton("BackgroundsButton", 241c9e8f97aSAdrien Destugues B_TRANSLATE("Set background" B_UTF8_ELLIPSIS), 242b21d610eSAxel Dörfler new BMessage(BUTTON_LAUNCH_BACKGROUNDS_MSG)); 243b21d610eSAxel Dörfler fBackgroundsButton->SetFontSize(be_plain_font->Size() * 0.9); 244b21d610eSAxel Dörfler screenBox->AddChild(fBackgroundsButton); 245a10cf76eSAxel Dörfler 246a10cf76eSAxel Dörfler // box on the right with screen resolution, etc. 247a10cf76eSAxel Dörfler 248b21d610eSAxel Dörfler BBox* controlsBox = new BBox("controls box"); 249b21d610eSAxel Dörfler controlsBox->SetLabel(workspaceMenuField); 25025fd5c7bSAlex Wilson BGroupView* outerControlsView = new BGroupView(B_VERTICAL, 10.0); 25125fd5c7bSAlex Wilson outerControlsView->GroupLayout()->SetInsets(10, 10, 10, 10); 252b21d610eSAxel Dörfler controlsBox->AddChild(outerControlsView); 253a10cf76eSAxel Dörfler 254551c9f15SSiarzhuk Zharski fResolutionMenu = new BPopUpMenu("resolution", true, true); 255a10cf76eSAxel Dörfler 25666ab1666SAxel Dörfler uint16 maxWidth = 0; 25766ab1666SAxel Dörfler uint16 maxHeight = 0; 25866ab1666SAxel Dörfler uint16 previousWidth = 0; 25966ab1666SAxel Dörfler uint16 previousHeight = 0; 260a10cf76eSAxel Dörfler for (int32 i = 0; i < fScreenMode.CountModes(); i++) { 261a10cf76eSAxel Dörfler screen_mode mode = fScreenMode.ModeAt(i); 262a10cf76eSAxel Dörfler 263a10cf76eSAxel Dörfler if (mode.width == previousWidth && mode.height == previousHeight) 264a10cf76eSAxel Dörfler continue; 265a10cf76eSAxel Dörfler 266a10cf76eSAxel Dörfler previousWidth = mode.width; 267a10cf76eSAxel Dörfler previousHeight = mode.height; 26866ab1666SAxel Dörfler if (maxWidth < mode.width) 26966ab1666SAxel Dörfler maxWidth = mode.width; 27066ab1666SAxel Dörfler if (maxHeight < mode.height) 27166ab1666SAxel Dörfler maxHeight = mode.height; 272a10cf76eSAxel Dörfler 273a10cf76eSAxel Dörfler BMessage* message = new BMessage(POP_RESOLUTION_MSG); 274a10cf76eSAxel Dörfler message->AddInt32("width", mode.width); 275a10cf76eSAxel Dörfler message->AddInt32("height", mode.height); 276a10cf76eSAxel Dörfler 277a10cf76eSAxel Dörfler BString name; 278a10cf76eSAxel Dörfler name << mode.width << " x " << mode.height; 279a10cf76eSAxel Dörfler 280a10cf76eSAxel Dörfler fResolutionMenu->AddItem(new BMenuItem(name.String(), message)); 281a10cf76eSAxel Dörfler } 282a10cf76eSAxel Dörfler 28366ab1666SAxel Dörfler fMonitorView->SetMaxResolution(maxWidth, maxHeight); 28466ab1666SAxel Dörfler 285c9e8f97aSAdrien Destugues fResolutionField = new BMenuField("ResolutionMenu", 286*10dfe897SAxel Dörfler B_TRANSLATE("Resolution:"), fResolutionMenu); 287a10cf76eSAxel Dörfler 288551c9f15SSiarzhuk Zharski fColorsMenu = new BPopUpMenu("colors", true, false); 289a10cf76eSAxel Dörfler 290a10cf76eSAxel Dörfler for (int32 i = 0; i < kColorSpaceCount; i++) { 2911fc4cb1fSAxel Dörfler if ((fSupportedColorSpaces & (1 << i)) == 0) 2921fc4cb1fSAxel Dörfler continue; 2931fc4cb1fSAxel Dörfler 294a10cf76eSAxel Dörfler BMessage* message = new BMessage(POP_COLORS_MSG); 295a10cf76eSAxel Dörfler message->AddInt32("bits_per_pixel", kColorSpaces[i].bits_per_pixel); 296a10cf76eSAxel Dörfler message->AddInt32("space", kColorSpaces[i].space); 297a10cf76eSAxel Dörfler 2981fc4cb1fSAxel Dörfler BMenuItem* item = new BMenuItem(kColorSpaces[i].label, message); 2991fc4cb1fSAxel Dörfler if (kColorSpaces[i].space == screen.ColorSpace()) 3001fc4cb1fSAxel Dörfler fUserSelectedColorSpace = item; 3011fc4cb1fSAxel Dörfler 3021fc4cb1fSAxel Dörfler fColorsMenu->AddItem(item); 303a10cf76eSAxel Dörfler } 304a10cf76eSAxel Dörfler 305c9e8f97aSAdrien Destugues fColorsField = new BMenuField("ColorsMenu", B_TRANSLATE("Colors:"), 306*10dfe897SAxel Dörfler fColorsMenu); 307a10cf76eSAxel Dörfler 308551c9f15SSiarzhuk Zharski fRefreshMenu = new BPopUpMenu("refresh rate", true, true); 309a10cf76eSAxel Dörfler 31029e8a73aSAxel Dörfler BMessage *message; 31129e8a73aSAxel Dörfler 31229e8a73aSAxel Dörfler float min, max; 31329e8a73aSAxel Dörfler if (fScreenMode.GetRefreshLimits(fActive, min, max) && min == max) { 31429e8a73aSAxel Dörfler // This is a special case for drivers that only support a single 31529e8a73aSAxel Dörfler // frequency, like the VESA driver 31629e8a73aSAxel Dörfler BString name; 317551c9f15SSiarzhuk Zharski name << min << " " << B_TRANSLATE("Hz"); 31829e8a73aSAxel Dörfler 31929e8a73aSAxel Dörfler message = new BMessage(POP_REFRESH_MSG); 32029e8a73aSAxel Dörfler message->AddFloat("refresh", min); 32129e8a73aSAxel Dörfler 32229e8a73aSAxel Dörfler fRefreshMenu->AddItem(item = new BMenuItem(name.String(), message)); 32329e8a73aSAxel Dörfler item->SetEnabled(false); 32429e8a73aSAxel Dörfler } else { 32570a2b1b5SAxel Dörfler monitor_info info; 32670a2b1b5SAxel Dörfler if (fScreenMode.GetMonitorInfo(info) == B_OK) { 32770a2b1b5SAxel Dörfler min = max_c(info.min_vertical_frequency, min); 32870a2b1b5SAxel Dörfler max = min_c(info.max_vertical_frequency, max); 32970a2b1b5SAxel Dörfler } 33070a2b1b5SAxel Dörfler 331a10cf76eSAxel Dörfler for (int32 i = 0; i < kRefreshRateCount; ++i) { 33270a2b1b5SAxel Dörfler if (kRefreshRates[i] < min || kRefreshRates[i] > max) 33370a2b1b5SAxel Dörfler continue; 33470a2b1b5SAxel Dörfler 335a10cf76eSAxel Dörfler BString name; 336551c9f15SSiarzhuk Zharski name << kRefreshRates[i] << " " << B_TRANSLATE("Hz"); 337a10cf76eSAxel Dörfler 33829e8a73aSAxel Dörfler message = new BMessage(POP_REFRESH_MSG); 339a10cf76eSAxel Dörfler message->AddFloat("refresh", kRefreshRates[i]); 340a10cf76eSAxel Dörfler 341a10cf76eSAxel Dörfler fRefreshMenu->AddItem(new BMenuItem(name.String(), message)); 342a10cf76eSAxel Dörfler } 343a10cf76eSAxel Dörfler 34429e8a73aSAxel Dörfler message = new BMessage(POP_OTHER_REFRESH_MSG); 345a10cf76eSAxel Dörfler 346c9e8f97aSAdrien Destugues fOtherRefresh = new BMenuItem(B_TRANSLATE("Other" B_UTF8_ELLIPSIS), 347c9e8f97aSAdrien Destugues message); 348a10cf76eSAxel Dörfler fRefreshMenu->AddItem(fOtherRefresh); 34929e8a73aSAxel Dörfler } 350a10cf76eSAxel Dörfler 351c9e8f97aSAdrien Destugues fRefreshField = new BMenuField("RefreshMenu", B_TRANSLATE("Refresh rate:"), 352*10dfe897SAxel Dörfler fRefreshMenu); 353b21d610eSAxel Dörfler 35412580984SAxel Dörfler if (_IsVesa()) 35512580984SAxel Dörfler fRefreshField->Hide(); 356a10cf76eSAxel Dörfler 357a10cf76eSAxel Dörfler // enlarged area for multi-monitor settings 358a10cf76eSAxel Dörfler { 359a10cf76eSAxel Dörfler bool dummy; 360a10cf76eSAxel Dörfler uint32 dummy32; 361a10cf76eSAxel Dörfler bool multiMonSupport; 362a10cf76eSAxel Dörfler bool useLaptopPanelSupport; 363a10cf76eSAxel Dörfler bool tvStandardSupport; 364a10cf76eSAxel Dörfler 365a10cf76eSAxel Dörfler multiMonSupport = TestMultiMonSupport(&screen) == B_OK; 366a10cf76eSAxel Dörfler useLaptopPanelSupport = GetUseLaptopPanel(&screen, &dummy) == B_OK; 367a10cf76eSAxel Dörfler tvStandardSupport = GetTVStandard(&screen, &dummy32) == B_OK; 368a10cf76eSAxel Dörfler 369a10cf76eSAxel Dörfler // even if there is no support, we still create all controls 370a10cf76eSAxel Dörfler // to make sure we don't access NULL pointers later on 371a10cf76eSAxel Dörfler 372551c9f15SSiarzhuk Zharski fCombineMenu = new BPopUpMenu("CombineDisplays", 373c9e8f97aSAdrien Destugues true, true); 374a10cf76eSAxel Dörfler 375a10cf76eSAxel Dörfler for (int32 i = 0; i < kCombineModeCount; i++) { 376a10cf76eSAxel Dörfler message = new BMessage(POP_COMBINE_DISPLAYS_MSG); 377a10cf76eSAxel Dörfler message->AddInt32("mode", kCombineModes[i].mode); 378a10cf76eSAxel Dörfler 379d1516993SAxel Dörfler fCombineMenu->AddItem(new BMenuItem(kCombineModes[i].name, 380d1516993SAxel Dörfler message)); 381a10cf76eSAxel Dörfler } 382a10cf76eSAxel Dörfler 383b21d610eSAxel Dörfler fCombineField = new BMenuField("CombineMenu", 384*10dfe897SAxel Dörfler B_TRANSLATE("Combine displays:"), fCombineMenu); 385a10cf76eSAxel Dörfler 386a10cf76eSAxel Dörfler if (!multiMonSupport) 387df3f5bacSStephan Aßmus fCombineField->Hide(); 388a10cf76eSAxel Dörfler 389551c9f15SSiarzhuk Zharski fSwapDisplaysMenu = new BPopUpMenu("SwapDisplays", 390c9e8f97aSAdrien Destugues true, true); 391a10cf76eSAxel Dörfler 392a10cf76eSAxel Dörfler // !order is important - we rely that boolean value == idx 393a10cf76eSAxel Dörfler message = new BMessage(POP_SWAP_DISPLAYS_MSG); 394a10cf76eSAxel Dörfler message->AddBool("swap", false); 395c9e8f97aSAdrien Destugues fSwapDisplaysMenu->AddItem(new BMenuItem(B_TRANSLATE("no"), message)); 396a10cf76eSAxel Dörfler 397a10cf76eSAxel Dörfler message = new BMessage(POP_SWAP_DISPLAYS_MSG); 398a10cf76eSAxel Dörfler message->AddBool("swap", true); 399c9e8f97aSAdrien Destugues fSwapDisplaysMenu->AddItem(new BMenuItem(B_TRANSLATE("yes"), message)); 400a10cf76eSAxel Dörfler 401c9e8f97aSAdrien Destugues fSwapDisplaysField = new BMenuField("SwapMenu", 402*10dfe897SAxel Dörfler B_TRANSLATE("Swap displays:"), fSwapDisplaysMenu); 403a10cf76eSAxel Dörfler 404a10cf76eSAxel Dörfler if (!multiMonSupport) 405df3f5bacSStephan Aßmus fSwapDisplaysField->Hide(); 406a10cf76eSAxel Dörfler 407551c9f15SSiarzhuk Zharski fUseLaptopPanelMenu = new BPopUpMenu("UseLaptopPanel", 408c9e8f97aSAdrien Destugues true, true); 409a10cf76eSAxel Dörfler 410a10cf76eSAxel Dörfler // !order is important - we rely that boolean value == idx 411a10cf76eSAxel Dörfler message = new BMessage(POP_USE_LAPTOP_PANEL_MSG); 412a10cf76eSAxel Dörfler message->AddBool("use", false); 413c9e8f97aSAdrien Destugues fUseLaptopPanelMenu->AddItem(new BMenuItem(B_TRANSLATE("if needed"), 414c9e8f97aSAdrien Destugues message)); 415a10cf76eSAxel Dörfler 416a10cf76eSAxel Dörfler message = new BMessage(POP_USE_LAPTOP_PANEL_MSG); 417a10cf76eSAxel Dörfler message->AddBool("use", true); 418c9e8f97aSAdrien Destugues fUseLaptopPanelMenu->AddItem(new BMenuItem(B_TRANSLATE("always"), 419c9e8f97aSAdrien Destugues message)); 420a10cf76eSAxel Dörfler 421b21d610eSAxel Dörfler fUseLaptopPanelField = new BMenuField("UseLaptopPanel", 422*10dfe897SAxel Dörfler B_TRANSLATE("Use laptop panel:"), fUseLaptopPanelMenu); 423a10cf76eSAxel Dörfler 424a10cf76eSAxel Dörfler if (!useLaptopPanelSupport) 425df3f5bacSStephan Aßmus fUseLaptopPanelField->Hide(); 426a10cf76eSAxel Dörfler 427551c9f15SSiarzhuk Zharski fTVStandardMenu = new BPopUpMenu("TVStandard", true, true); 428a10cf76eSAxel Dörfler 429a10cf76eSAxel Dörfler // arbitrary limit 430a10cf76eSAxel Dörfler uint32 i; 431a10cf76eSAxel Dörfler for (i = 0; i < 100; ++i) { 432a10cf76eSAxel Dörfler uint32 mode; 433a10cf76eSAxel Dörfler if (GetNthSupportedTVStandard(&screen, i, &mode) != B_OK) 434a10cf76eSAxel Dörfler break; 435a10cf76eSAxel Dörfler 436a10cf76eSAxel Dörfler BString name = tv_standard_to_string(mode); 437a10cf76eSAxel Dörfler 438a10cf76eSAxel Dörfler message = new BMessage(POP_TV_STANDARD_MSG); 439a10cf76eSAxel Dörfler message->AddInt32("tv_standard", mode); 440a10cf76eSAxel Dörfler 441a10cf76eSAxel Dörfler fTVStandardMenu->AddItem(new BMenuItem(name.String(), message)); 442a10cf76eSAxel Dörfler } 443a10cf76eSAxel Dörfler 444c9e8f97aSAdrien Destugues fTVStandardField = new BMenuField("tv standard", 445*10dfe897SAxel Dörfler B_TRANSLATE("Video format:"), fTVStandardMenu); 446df3f5bacSStephan Aßmus fTVStandardField->SetAlignment(B_ALIGN_RIGHT); 447a10cf76eSAxel Dörfler 448b21d610eSAxel Dörfler if (!tvStandardSupport || i == 0) 449df3f5bacSStephan Aßmus fTVStandardField->Hide(); 450a10cf76eSAxel Dörfler } 451a10cf76eSAxel Dörfler 45225fd5c7bSAlex Wilson BLayoutBuilder::Group<>(outerControlsView) 45325fd5c7bSAlex Wilson .AddGrid(5.0, 5.0) 454b21d610eSAxel Dörfler .AddMenuField(fResolutionField, 0, 0, B_ALIGN_RIGHT) 455b21d610eSAxel Dörfler .AddMenuField(fColorsField, 0, 1, B_ALIGN_RIGHT) 456b21d610eSAxel Dörfler .AddMenuField(fRefreshField, 0, 2, B_ALIGN_RIGHT) 457b21d610eSAxel Dörfler .AddMenuField(fCombineField, 0, 3, B_ALIGN_RIGHT) 458b21d610eSAxel Dörfler .AddMenuField(fSwapDisplaysField, 0, 4, B_ALIGN_RIGHT) 459b21d610eSAxel Dörfler .AddMenuField(fUseLaptopPanelField, 0, 5, B_ALIGN_RIGHT) 46025fd5c7bSAlex Wilson .AddMenuField(fTVStandardField, 0, 6, B_ALIGN_RIGHT) 46125fd5c7bSAlex Wilson .End(); 462df3f5bacSStephan Aßmus 463abc649b8SWaldemar Kornewald // TODO: we don't support getting the screen's preferred settings 464abc649b8SWaldemar Kornewald /* fDefaultsButton = new BButton(buttonRect, "DefaultsButton", "Defaults", 465b21d610eSAxel Dörfler new BMessage(BUTTON_DEFAULTS_MSG));*/ 466a10cf76eSAxel Dörfler 467c9e8f97aSAdrien Destugues fApplyButton = new BButton("ApplyButton", B_TRANSLATE("Apply"), 468df3f5bacSStephan Aßmus new BMessage(BUTTON_APPLY_MSG)); 469df3f5bacSStephan Aßmus fApplyButton->SetEnabled(false); 47025fd5c7bSAlex Wilson BLayoutBuilder::Group<>(outerControlsView) 471b21d610eSAxel Dörfler .AddGlue() 47225fd5c7bSAlex Wilson .AddGroup(B_HORIZONTAL) 47325fd5c7bSAlex Wilson .AddGlue() 47425fd5c7bSAlex Wilson .Add(fApplyButton); 475b21d610eSAxel Dörfler 476c9e8f97aSAdrien Destugues fRevertButton = new BButton("RevertButton", B_TRANSLATE("Revert"), 477b21d610eSAxel Dörfler new BMessage(BUTTON_REVERT_MSG)); 478b21d610eSAxel Dörfler fRevertButton->SetEnabled(false); 479b21d610eSAxel Dörfler 48025fd5c7bSAlex Wilson BLayoutBuilder::Group<>(this, B_VERTICAL, 10.0) 481b21d610eSAxel Dörfler .SetInsets(10, 10, 10, 10) 482b21d610eSAxel Dörfler .AddGroup(B_HORIZONTAL, 10.0) 483b21d610eSAxel Dörfler .AddGroup(B_VERTICAL) 48425fd5c7bSAlex Wilson .AddStrut(controlsBox->TopBorderOffset() - 1) 485b21d610eSAxel Dörfler .Add(screenBox) 486b21d610eSAxel Dörfler .End() 487b21d610eSAxel Dörfler .Add(controlsBox) 488b21d610eSAxel Dörfler .End() 489b21d610eSAxel Dörfler .AddGroup(B_HORIZONTAL, 10.0) 490b21d610eSAxel Dörfler .Add(fRevertButton) 491b21d610eSAxel Dörfler .AddGlue(); 492b21d610eSAxel Dörfler 4935de171daSAxel Dörfler _UpdateControls(); 49412966d04SAxel Dörfler _UpdateMonitor(); 495a10cf76eSAxel Dörfler } 496a10cf76eSAxel Dörfler 497a10cf76eSAxel Dörfler 498a10cf76eSAxel Dörfler ScreenWindow::~ScreenWindow() 499a10cf76eSAxel Dörfler { 500a10cf76eSAxel Dörfler delete fSettings; 501a10cf76eSAxel Dörfler } 502a10cf76eSAxel Dörfler 503a10cf76eSAxel Dörfler 504a10cf76eSAxel Dörfler bool 505a10cf76eSAxel Dörfler ScreenWindow::QuitRequested() 506a10cf76eSAxel Dörfler { 507a10cf76eSAxel Dörfler fSettings->SetWindowFrame(Frame()); 508199893c3SAxel Dörfler 509199893c3SAxel Dörfler // Write mode of workspace 0 (the boot workspace) to the vesa settings file 510199893c3SAxel Dörfler screen_mode vesaMode; 511199893c3SAxel Dörfler if (fBootWorkspaceApplied && fScreenMode.Get(vesaMode, 0) == B_OK) { 512199893c3SAxel Dörfler status_t status = _WriteVesaModeFile(vesaMode); 51312580984SAxel Dörfler if (status < B_OK) { 514c9e8f97aSAdrien Destugues BString warning = B_TRANSLATE("Could not write VESA mode settings" 515c9e8f97aSAdrien Destugues " file:\n\t"); 51612580984SAxel Dörfler warning << strerror(status); 517551c9f15SSiarzhuk Zharski (new BAlert(B_TRANSLATE("Warning"), warning.String(), B_TRANSLATE("OK"), NULL, 518c9e8f97aSAdrien Destugues NULL, B_WIDTH_AS_USUAL, B_WARNING_ALERT))->Go(); 51912580984SAxel Dörfler } 52012580984SAxel Dörfler } 52112580984SAxel Dörfler 522a10cf76eSAxel Dörfler be_app->PostMessage(B_QUIT_REQUESTED); 523a10cf76eSAxel Dörfler 524a10cf76eSAxel Dörfler return BWindow::QuitRequested(); 525a10cf76eSAxel Dörfler } 526a10cf76eSAxel Dörfler 527a10cf76eSAxel Dörfler 5285de171daSAxel Dörfler /*! Update resolution list according to combine mode 5291fc4cb1fSAxel Dörfler (some resolutions may not be combinable due to memory restrictions). 530a10cf76eSAxel Dörfler */ 531a10cf76eSAxel Dörfler void 5325de171daSAxel Dörfler ScreenWindow::_CheckResolutionMenu() 533a10cf76eSAxel Dörfler { 534a10cf76eSAxel Dörfler for (int32 i = 0; i < fResolutionMenu->CountItems(); i++) 535a10cf76eSAxel Dörfler fResolutionMenu->ItemAt(i)->SetEnabled(false); 536a10cf76eSAxel Dörfler 537a10cf76eSAxel Dörfler for (int32 i = 0; i < fScreenMode.CountModes(); i++) { 538a10cf76eSAxel Dörfler screen_mode mode = fScreenMode.ModeAt(i); 539a10cf76eSAxel Dörfler if (mode.combine != fSelected.combine) 540a10cf76eSAxel Dörfler continue; 541a10cf76eSAxel Dörfler 542a10cf76eSAxel Dörfler BString name; 543a10cf76eSAxel Dörfler name << mode.width << " x " << mode.height; 544a10cf76eSAxel Dörfler 545a10cf76eSAxel Dörfler BMenuItem *item = fResolutionMenu->FindItem(name.String()); 546a10cf76eSAxel Dörfler if (item != NULL) 547a10cf76eSAxel Dörfler item->SetEnabled(true); 548a10cf76eSAxel Dörfler } 549a10cf76eSAxel Dörfler } 550a10cf76eSAxel Dörfler 551a10cf76eSAxel Dörfler 5525de171daSAxel Dörfler /*! Update color and refresh options according to current mode 5535de171daSAxel Dörfler (a color space is made active if there is any mode with 5545de171daSAxel Dörfler given resolution and this colour space; same applies for 5555de171daSAxel Dörfler refresh rate, though "Other…" is always possible) 556a10cf76eSAxel Dörfler */ 557a10cf76eSAxel Dörfler void 5585de171daSAxel Dörfler ScreenWindow::_CheckColorMenu() 559a10cf76eSAxel Dörfler { 5601fc4cb1fSAxel Dörfler int32 supportsAnything = false; 5611fc4cb1fSAxel Dörfler int32 index = 0; 5621fc4cb1fSAxel Dörfler 563a10cf76eSAxel Dörfler for (int32 i = 0; i < kColorSpaceCount; i++) { 5641fc4cb1fSAxel Dörfler if ((fSupportedColorSpaces & (1 << i)) == 0) 5651fc4cb1fSAxel Dörfler continue; 5661fc4cb1fSAxel Dörfler 567a10cf76eSAxel Dörfler bool supported = false; 568a10cf76eSAxel Dörfler 569a10cf76eSAxel Dörfler for (int32 j = 0; j < fScreenMode.CountModes(); j++) { 570a10cf76eSAxel Dörfler screen_mode mode = fScreenMode.ModeAt(j); 571a10cf76eSAxel Dörfler 572a10cf76eSAxel Dörfler if (fSelected.width == mode.width 573a10cf76eSAxel Dörfler && fSelected.height == mode.height 5741fc4cb1fSAxel Dörfler && kColorSpaces[i].space == mode.space 575a10cf76eSAxel Dörfler && fSelected.combine == mode.combine) { 5761fc4cb1fSAxel Dörfler supportsAnything = true; 577a10cf76eSAxel Dörfler supported = true; 578a10cf76eSAxel Dörfler break; 579a10cf76eSAxel Dörfler } 580a10cf76eSAxel Dörfler } 581a10cf76eSAxel Dörfler 5821fc4cb1fSAxel Dörfler BMenuItem* item = fColorsMenu->ItemAt(index++); 583a10cf76eSAxel Dörfler if (item) 584a10cf76eSAxel Dörfler item->SetEnabled(supported); 585a10cf76eSAxel Dörfler } 5861fc4cb1fSAxel Dörfler 5871fc4cb1fSAxel Dörfler fColorsField->SetEnabled(supportsAnything); 5881fc4cb1fSAxel Dörfler 5891fc4cb1fSAxel Dörfler if (!supportsAnything) 5901fc4cb1fSAxel Dörfler return; 5911fc4cb1fSAxel Dörfler 5921fc4cb1fSAxel Dörfler // Make sure a valid item is selected 5931fc4cb1fSAxel Dörfler 5941fc4cb1fSAxel Dörfler BMenuItem* item = fColorsMenu->FindMarked(); 5951fc4cb1fSAxel Dörfler bool changed = false; 5961fc4cb1fSAxel Dörfler 5971fc4cb1fSAxel Dörfler if (item != fUserSelectedColorSpace) { 5981fc4cb1fSAxel Dörfler if (fUserSelectedColorSpace != NULL 5991fc4cb1fSAxel Dörfler && fUserSelectedColorSpace->IsEnabled()) { 6001fc4cb1fSAxel Dörfler fUserSelectedColorSpace->SetMarked(true); 6011fc4cb1fSAxel Dörfler item = fUserSelectedColorSpace; 6021fc4cb1fSAxel Dörfler changed = true; 6031fc4cb1fSAxel Dörfler } 6041fc4cb1fSAxel Dörfler } 6051fc4cb1fSAxel Dörfler if (item != NULL && !item->IsEnabled()) { 6061fc4cb1fSAxel Dörfler // find the next best item 6071fc4cb1fSAxel Dörfler int32 index = fColorsMenu->IndexOf(item); 6081fc4cb1fSAxel Dörfler bool found = false; 6091fc4cb1fSAxel Dörfler 6101fc4cb1fSAxel Dörfler for (int32 i = index + 1; i < fColorsMenu->CountItems(); i++) { 6111fc4cb1fSAxel Dörfler item = fColorsMenu->ItemAt(i); 6121fc4cb1fSAxel Dörfler if (item->IsEnabled()) { 6131fc4cb1fSAxel Dörfler found = true; 6141fc4cb1fSAxel Dörfler break; 6151fc4cb1fSAxel Dörfler } 6161fc4cb1fSAxel Dörfler } 6171fc4cb1fSAxel Dörfler if (!found) { 6181fc4cb1fSAxel Dörfler // search backwards as well 6191fc4cb1fSAxel Dörfler for (int32 i = index - 1; i >= 0; i--) { 6201fc4cb1fSAxel Dörfler item = fColorsMenu->ItemAt(i); 6211fc4cb1fSAxel Dörfler if (item->IsEnabled()) 6221fc4cb1fSAxel Dörfler break; 6231fc4cb1fSAxel Dörfler } 6241fc4cb1fSAxel Dörfler } 6251fc4cb1fSAxel Dörfler 6261fc4cb1fSAxel Dörfler item->SetMarked(true); 6271fc4cb1fSAxel Dörfler changed = true; 6281fc4cb1fSAxel Dörfler } 6291fc4cb1fSAxel Dörfler 6301fc4cb1fSAxel Dörfler if (changed) { 6311fc4cb1fSAxel Dörfler // Update selected space 6321fc4cb1fSAxel Dörfler 6331fc4cb1fSAxel Dörfler BMessage* message = item->Message(); 6341fc4cb1fSAxel Dörfler int32 space; 6351fc4cb1fSAxel Dörfler if (message->FindInt32("space", &space) == B_OK) { 6361fc4cb1fSAxel Dörfler fSelected.space = (color_space)space; 6371fc4cb1fSAxel Dörfler _UpdateColorLabel(); 6381fc4cb1fSAxel Dörfler } 6391fc4cb1fSAxel Dörfler } 640a10cf76eSAxel Dörfler } 641a10cf76eSAxel Dörfler 642a10cf76eSAxel Dörfler 6435de171daSAxel Dörfler /*! Enable/disable refresh options according to current mode. */ 644a10cf76eSAxel Dörfler void 6455de171daSAxel Dörfler ScreenWindow::_CheckRefreshMenu() 646a10cf76eSAxel Dörfler { 64729e8a73aSAxel Dörfler float min, max; 64829e8a73aSAxel Dörfler if (fScreenMode.GetRefreshLimits(fSelected, min, max) != B_OK || min == max) 64929e8a73aSAxel Dörfler return; 650a10cf76eSAxel Dörfler 65129e8a73aSAxel Dörfler for (int32 i = fRefreshMenu->CountItems(); i-- > 0;) { 65229e8a73aSAxel Dörfler BMenuItem* item = fRefreshMenu->ItemAt(i); 65329e8a73aSAxel Dörfler BMessage* message = item->Message(); 65429e8a73aSAxel Dörfler float refresh; 65529e8a73aSAxel Dörfler if (message != NULL && message->FindFloat("refresh", &refresh) == B_OK) 65629e8a73aSAxel Dörfler item->SetEnabled(refresh >= min && refresh <= max); 657a10cf76eSAxel Dörfler } 658a10cf76eSAxel Dörfler } 659a10cf76eSAxel Dörfler 660a10cf76eSAxel Dörfler 6615de171daSAxel Dörfler /*! Activate appropriate menu item according to selected refresh rate */ 662a10cf76eSAxel Dörfler void 6635de171daSAxel Dörfler ScreenWindow::_UpdateRefreshControl() 664a10cf76eSAxel Dörfler { 665a10cf76eSAxel Dörfler BString string; 666a10cf76eSAxel Dörfler refresh_rate_to_string(fSelected.refresh, string); 667a10cf76eSAxel Dörfler 668a10cf76eSAxel Dörfler BMenuItem* item = fRefreshMenu->FindItem(string.String()); 669a10cf76eSAxel Dörfler if (item) { 670a10cf76eSAxel Dörfler if (!item->IsMarked()) 671a10cf76eSAxel Dörfler item->SetMarked(true); 67229e8a73aSAxel Dörfler 67326747978SAdrien Destugues // "Other" items only contains a refresh rate when active 67426747978SAdrien Destugues fOtherRefresh->SetLabel(B_TRANSLATE("Other" B_UTF8_ELLIPSIS)); 675a10cf76eSAxel Dörfler return; 676a10cf76eSAxel Dörfler } 677a10cf76eSAxel Dörfler 678a10cf76eSAxel Dörfler // this is a non-standard refresh rate 679a10cf76eSAxel Dörfler 680a10cf76eSAxel Dörfler fOtherRefresh->Message()->ReplaceFloat("refresh", fSelected.refresh); 681a10cf76eSAxel Dörfler fOtherRefresh->SetMarked(true); 682a10cf76eSAxel Dörfler 683a10cf76eSAxel Dörfler fRefreshMenu->Superitem()->SetLabel(string.String()); 684a10cf76eSAxel Dörfler 685c9e8f97aSAdrien Destugues string.Append(B_TRANSLATE("/other" B_UTF8_ELLIPSIS)); 686a10cf76eSAxel Dörfler fOtherRefresh->SetLabel(string.String()); 687a10cf76eSAxel Dörfler } 688a10cf76eSAxel Dörfler 689a10cf76eSAxel Dörfler 690a10cf76eSAxel Dörfler void 6915de171daSAxel Dörfler ScreenWindow::_UpdateMonitorView() 692a10cf76eSAxel Dörfler { 693a10cf76eSAxel Dörfler BMessage updateMessage(UPDATE_DESKTOP_MSG); 694a10cf76eSAxel Dörfler updateMessage.AddInt32("width", fSelected.width); 695a10cf76eSAxel Dörfler updateMessage.AddInt32("height", fSelected.height); 696a10cf76eSAxel Dörfler 697a10cf76eSAxel Dörfler PostMessage(&updateMessage, fMonitorView); 698a10cf76eSAxel Dörfler } 699a10cf76eSAxel Dörfler 700a10cf76eSAxel Dörfler 701a10cf76eSAxel Dörfler void 7025de171daSAxel Dörfler ScreenWindow::_UpdateControls() 703a10cf76eSAxel Dörfler { 704b21d610eSAxel Dörfler _UpdateWorkspaceButtons(); 705b21d610eSAxel Dörfler 706a10cf76eSAxel Dörfler BMenuItem* item = fSwapDisplaysMenu->ItemAt((int32)fSelected.swap_displays); 707a10cf76eSAxel Dörfler if (item && !item->IsMarked()) 708a10cf76eSAxel Dörfler item->SetMarked(true); 709a10cf76eSAxel Dörfler 710a10cf76eSAxel Dörfler item = fUseLaptopPanelMenu->ItemAt((int32)fSelected.use_laptop_panel); 711a10cf76eSAxel Dörfler if (item && !item->IsMarked()) 712a10cf76eSAxel Dörfler item->SetMarked(true); 713a10cf76eSAxel Dörfler 714a10cf76eSAxel Dörfler for (int32 i = 0; i < fTVStandardMenu->CountItems(); i++) { 715a10cf76eSAxel Dörfler item = fTVStandardMenu->ItemAt(i); 716a10cf76eSAxel Dörfler 717a10cf76eSAxel Dörfler uint32 tvStandard; 718a10cf76eSAxel Dörfler item->Message()->FindInt32("tv_standard", (int32 *)&tvStandard); 719a10cf76eSAxel Dörfler if (tvStandard == fSelected.tv_standard) { 720a10cf76eSAxel Dörfler if (!item->IsMarked()) 721a10cf76eSAxel Dörfler item->SetMarked(true); 722a10cf76eSAxel Dörfler break; 723a10cf76eSAxel Dörfler } 724a10cf76eSAxel Dörfler } 725a10cf76eSAxel Dörfler 7265de171daSAxel Dörfler _CheckResolutionMenu(); 7275de171daSAxel Dörfler _CheckColorMenu(); 7285de171daSAxel Dörfler _CheckRefreshMenu(); 729a10cf76eSAxel Dörfler 730a10cf76eSAxel Dörfler BString string; 731a10cf76eSAxel Dörfler resolution_to_string(fSelected, string); 732a10cf76eSAxel Dörfler item = fResolutionMenu->FindItem(string.String()); 733a10cf76eSAxel Dörfler 734a10cf76eSAxel Dörfler if (item != NULL) { 735a10cf76eSAxel Dörfler if (!item->IsMarked()) 736a10cf76eSAxel Dörfler item->SetMarked(true); 737a10cf76eSAxel Dörfler } else { 738a10cf76eSAxel Dörfler // this is bad luck - if mode has been set via screen references, 739a10cf76eSAxel Dörfler // this case cannot occur; there are three possible solutions: 740a10cf76eSAxel Dörfler // 1. add a new resolution to list 741a10cf76eSAxel Dörfler // - we had to remove it as soon as a "valid" one is selected 742a10cf76eSAxel Dörfler // - we don't know which frequencies/bit depths are supported 743a10cf76eSAxel Dörfler // - as long as we haven't the GMT formula to create 744a10cf76eSAxel Dörfler // parameters for any resolution given, we cannot 745a10cf76eSAxel Dörfler // really set current mode - it's just not in the list 746a10cf76eSAxel Dörfler // 2. choose nearest resolution 747a10cf76eSAxel Dörfler // - probably a good idea, but implies coding and testing 748a10cf76eSAxel Dörfler // 3. choose lowest resolution 749a10cf76eSAxel Dörfler // - do you really think we are so lazy? yes, we are 750a10cf76eSAxel Dörfler item = fResolutionMenu->ItemAt(0); 751a10cf76eSAxel Dörfler if (item) 752a10cf76eSAxel Dörfler item->SetMarked(true); 753a10cf76eSAxel Dörfler 754a10cf76eSAxel Dörfler // okay - at least we set menu label to active resolution 755a10cf76eSAxel Dörfler fResolutionMenu->Superitem()->SetLabel(string.String()); 756a10cf76eSAxel Dörfler } 757a10cf76eSAxel Dörfler 758a10cf76eSAxel Dörfler // mark active combine mode 759a10cf76eSAxel Dörfler for (int32 i = 0; i < kCombineModeCount; i++) { 760a10cf76eSAxel Dörfler if (kCombineModes[i].mode == fSelected.combine) { 761a10cf76eSAxel Dörfler item = fCombineMenu->ItemAt(i); 762a10cf76eSAxel Dörfler if (item && !item->IsMarked()) 763a10cf76eSAxel Dörfler item->SetMarked(true); 764a10cf76eSAxel Dörfler break; 765a10cf76eSAxel Dörfler } 766a10cf76eSAxel Dörfler } 767a10cf76eSAxel Dörfler 768a10cf76eSAxel Dörfler item = fColorsMenu->ItemAt(0); 769a10cf76eSAxel Dörfler 7701fc4cb1fSAxel Dörfler for (int32 i = 0, index = 0; i < kColorSpaceCount; i++) { 7711fc4cb1fSAxel Dörfler if ((fSupportedColorSpaces & (1 << i)) == 0) 7721fc4cb1fSAxel Dörfler continue; 7731fc4cb1fSAxel Dörfler 7741fc4cb1fSAxel Dörfler if (kColorSpaces[i].space == fSelected.space) { 7751fc4cb1fSAxel Dörfler item = fColorsMenu->ItemAt(index); 776a10cf76eSAxel Dörfler break; 777a10cf76eSAxel Dörfler } 7781fc4cb1fSAxel Dörfler 7791fc4cb1fSAxel Dörfler index++; 780a10cf76eSAxel Dörfler } 781a10cf76eSAxel Dörfler 782a10cf76eSAxel Dörfler if (item && !item->IsMarked()) 783a10cf76eSAxel Dörfler item->SetMarked(true); 784a10cf76eSAxel Dörfler 7851fc4cb1fSAxel Dörfler _UpdateColorLabel(); 7865de171daSAxel Dörfler _UpdateMonitorView(); 7875de171daSAxel Dörfler _UpdateRefreshControl(); 788a10cf76eSAxel Dörfler 7895de171daSAxel Dörfler _CheckApplyEnabled(); 790a10cf76eSAxel Dörfler } 791a10cf76eSAxel Dörfler 792a10cf76eSAxel Dörfler 79312580984SAxel Dörfler /*! Reflect active mode in chosen settings */ 794a10cf76eSAxel Dörfler void 7955de171daSAxel Dörfler ScreenWindow::_UpdateActiveMode() 796a10cf76eSAxel Dörfler { 79712580984SAxel Dörfler // Usually, this function gets called after a mode 798a10cf76eSAxel Dörfler // has been set manually; still, as the graphics driver 799a10cf76eSAxel Dörfler // is free to fiddle with mode passed, we better ask 800a10cf76eSAxel Dörfler // what kind of mode we actually got 801a10cf76eSAxel Dörfler fScreenMode.Get(fActive); 802a10cf76eSAxel Dörfler fSelected = fActive; 803a10cf76eSAxel Dörfler 80412966d04SAxel Dörfler _UpdateMonitor(); 8055de171daSAxel Dörfler _UpdateControls(); 806a10cf76eSAxel Dörfler } 807a10cf76eSAxel Dörfler 808a10cf76eSAxel Dörfler 809a10cf76eSAxel Dörfler void 810b21d610eSAxel Dörfler ScreenWindow::_UpdateWorkspaceButtons() 811b21d610eSAxel Dörfler { 812b21d610eSAxel Dörfler uint32 columns; 813b21d610eSAxel Dörfler uint32 rows; 814b21d610eSAxel Dörfler BPrivate::get_workspaces_layout(&columns, &rows); 815b21d610eSAxel Dörfler 816b21d610eSAxel Dörfler char text[32]; 817b21d610eSAxel Dörfler snprintf(text, sizeof(text), "%ld", columns); 818b21d610eSAxel Dörfler fColumnsControl->SetText(text); 819b21d610eSAxel Dörfler 820b21d610eSAxel Dörfler snprintf(text, sizeof(text), "%ld", rows); 821b21d610eSAxel Dörfler fRowsControl->SetText(text); 822b21d610eSAxel Dörfler 823b21d610eSAxel Dörfler _GetColumnRowButton(true, false)->SetEnabled(columns != 1 && rows != 32); 824b21d610eSAxel Dörfler _GetColumnRowButton(true, true)->SetEnabled((columns + 1) * rows < 32); 825b21d610eSAxel Dörfler _GetColumnRowButton(false, false)->SetEnabled(rows != 1 && columns != 32); 826b21d610eSAxel Dörfler _GetColumnRowButton(false, true)->SetEnabled(columns * (rows + 1) < 32); 827b21d610eSAxel Dörfler } 828b21d610eSAxel Dörfler 829b21d610eSAxel Dörfler 830b21d610eSAxel Dörfler void 831a10cf76eSAxel Dörfler ScreenWindow::ScreenChanged(BRect frame, color_space mode) 832a10cf76eSAxel Dörfler { 833a10cf76eSAxel Dörfler // move window on screen, if necessary 834a10cf76eSAxel Dörfler if (frame.right <= Frame().right 835a10cf76eSAxel Dörfler && frame.bottom <= Frame().bottom) { 836a10cf76eSAxel Dörfler MoveTo((frame.Width() - Frame().Width()) / 2, 837a10cf76eSAxel Dörfler (frame.Height() - Frame().Height()) / 2); 838a10cf76eSAxel Dörfler } 839a10cf76eSAxel Dörfler } 840a10cf76eSAxel Dörfler 841a10cf76eSAxel Dörfler 842a10cf76eSAxel Dörfler void 843a10cf76eSAxel Dörfler ScreenWindow::WorkspaceActivated(int32 workspace, bool state) 844a10cf76eSAxel Dörfler { 845abc649b8SWaldemar Kornewald fScreenMode.GetOriginalMode(fOriginal, workspace); 8465de171daSAxel Dörfler _UpdateActiveMode(); 847a10cf76eSAxel Dörfler 8486edaa0f6SStefano Ceccherini BMessage message(UPDATE_DESKTOP_COLOR_MSG); 8496edaa0f6SStefano Ceccherini PostMessage(&message, fMonitorView); 850a10cf76eSAxel Dörfler } 851a10cf76eSAxel Dörfler 852a10cf76eSAxel Dörfler 853a10cf76eSAxel Dörfler void 854a10cf76eSAxel Dörfler ScreenWindow::MessageReceived(BMessage* message) 855a10cf76eSAxel Dörfler { 856a10cf76eSAxel Dörfler switch (message->what) { 857a10cf76eSAxel Dörfler case WORKSPACE_CHECK_MSG: 8585de171daSAxel Dörfler _CheckApplyEnabled(); 859a10cf76eSAxel Dörfler break; 860a10cf76eSAxel Dörfler 861b21d610eSAxel Dörfler case kMsgWorkspaceLayoutChanged: 862a10cf76eSAxel Dörfler { 863b21d610eSAxel Dörfler int32 deltaX = 0; 864b21d610eSAxel Dörfler int32 deltaY = 0; 865b21d610eSAxel Dörfler message->FindInt32("delta_x", &deltaX); 866b21d610eSAxel Dörfler message->FindInt32("delta_y", &deltaY); 867b21d610eSAxel Dörfler 868b21d610eSAxel Dörfler if (deltaX == 0 && deltaY == 0) 869b21d610eSAxel Dörfler break; 870b21d610eSAxel Dörfler 871b21d610eSAxel Dörfler uint32 newColumns; 872b21d610eSAxel Dörfler uint32 newRows; 873b21d610eSAxel Dörfler BPrivate::get_workspaces_layout(&newColumns, &newRows); 874b21d610eSAxel Dörfler 875b21d610eSAxel Dörfler newColumns += deltaX; 876b21d610eSAxel Dörfler newRows += deltaY; 877b21d610eSAxel Dörfler BPrivate::set_workspaces_layout(newColumns, newRows); 878b21d610eSAxel Dörfler 879b21d610eSAxel Dörfler _UpdateWorkspaceButtons(); 8805de171daSAxel Dörfler _CheckApplyEnabled(); 881b21d610eSAxel Dörfler break; 882abc649b8SWaldemar Kornewald } 883b21d610eSAxel Dörfler 884b21d610eSAxel Dörfler case kMsgWorkspaceColumnsChanged: 885b21d610eSAxel Dörfler { 886b21d610eSAxel Dörfler uint32 newColumns = strtoul(fColumnsControl->Text(), NULL, 10); 887b21d610eSAxel Dörfler 888b21d610eSAxel Dörfler uint32 rows; 889b21d610eSAxel Dörfler BPrivate::get_workspaces_layout(NULL, &rows); 890b21d610eSAxel Dörfler BPrivate::set_workspaces_layout(newColumns, rows); 891b21d610eSAxel Dörfler 892b21d610eSAxel Dörfler _UpdateWorkspaceButtons(); 893b21d610eSAxel Dörfler _CheckApplyEnabled(); 894b21d610eSAxel Dörfler break; 895b21d610eSAxel Dörfler } 896b21d610eSAxel Dörfler 897b21d610eSAxel Dörfler case kMsgWorkspaceRowsChanged: 898b21d610eSAxel Dörfler { 899b21d610eSAxel Dörfler uint32 newRows = strtoul(fRowsControl->Text(), NULL, 10); 900b21d610eSAxel Dörfler 901b21d610eSAxel Dörfler uint32 columns; 902b21d610eSAxel Dörfler BPrivate::get_workspaces_layout(&columns, NULL); 903b21d610eSAxel Dörfler BPrivate::set_workspaces_layout(columns, newRows); 904b21d610eSAxel Dörfler 905b21d610eSAxel Dörfler _UpdateWorkspaceButtons(); 906b21d610eSAxel Dörfler _CheckApplyEnabled(); 907a10cf76eSAxel Dörfler break; 908a10cf76eSAxel Dörfler } 909a10cf76eSAxel Dörfler 910a10cf76eSAxel Dörfler case POP_RESOLUTION_MSG: 911a10cf76eSAxel Dörfler { 912a10cf76eSAxel Dörfler message->FindInt32("width", &fSelected.width); 913a10cf76eSAxel Dörfler message->FindInt32("height", &fSelected.height); 914a10cf76eSAxel Dörfler 9155de171daSAxel Dörfler _CheckColorMenu(); 9165de171daSAxel Dörfler _CheckRefreshMenu(); 917a10cf76eSAxel Dörfler 9185de171daSAxel Dörfler _UpdateMonitorView(); 9195de171daSAxel Dörfler _UpdateRefreshControl(); 920a10cf76eSAxel Dörfler 9215de171daSAxel Dörfler _CheckApplyEnabled(); 922a10cf76eSAxel Dörfler break; 923a10cf76eSAxel Dörfler } 924a10cf76eSAxel Dörfler 925a10cf76eSAxel Dörfler case POP_COLORS_MSG: 926a10cf76eSAxel Dörfler { 9271fc4cb1fSAxel Dörfler int32 space; 9281fc4cb1fSAxel Dörfler if (message->FindInt32("space", &space) != B_OK) 9291fc4cb1fSAxel Dörfler break; 930a10cf76eSAxel Dörfler 9311fc4cb1fSAxel Dörfler int32 index; 9321fc4cb1fSAxel Dörfler if (message->FindInt32("index", &index) == B_OK 9331fc4cb1fSAxel Dörfler && fColorsMenu->ItemAt(index) != NULL) 9341fc4cb1fSAxel Dörfler fUserSelectedColorSpace = fColorsMenu->ItemAt(index); 9351fc4cb1fSAxel Dörfler 9361fc4cb1fSAxel Dörfler fSelected.space = (color_space)space; 9371fc4cb1fSAxel Dörfler _UpdateColorLabel(); 938a10cf76eSAxel Dörfler 9395de171daSAxel Dörfler _CheckApplyEnabled(); 940a10cf76eSAxel Dörfler break; 941a10cf76eSAxel Dörfler } 942a10cf76eSAxel Dörfler 943a10cf76eSAxel Dörfler case POP_REFRESH_MSG: 944a40498e2SWaldemar Kornewald { 945a10cf76eSAxel Dörfler message->FindFloat("refresh", &fSelected.refresh); 946c9e8f97aSAdrien Destugues fOtherRefresh->SetLabel(B_TRANSLATE("Other" B_UTF8_ELLIPSIS)); 9471fc4cb1fSAxel Dörfler // revert "Other…" label - it might have a refresh rate prefix 948a10cf76eSAxel Dörfler 9495de171daSAxel Dörfler _CheckApplyEnabled(); 950a10cf76eSAxel Dörfler break; 951a40498e2SWaldemar Kornewald } 952a10cf76eSAxel Dörfler 953a10cf76eSAxel Dörfler case POP_OTHER_REFRESH_MSG: 954a10cf76eSAxel Dörfler { 95529e8a73aSAxel Dörfler // make sure menu shows something useful 9565de171daSAxel Dörfler _UpdateRefreshControl(); 957a10cf76eSAxel Dörfler 95829e8a73aSAxel Dörfler float min = 0, max = 999; 95929e8a73aSAxel Dörfler fScreenMode.GetRefreshLimits(fSelected, min, max); 96029e8a73aSAxel Dörfler if (min < gMinRefresh) 96129e8a73aSAxel Dörfler min = gMinRefresh; 96229e8a73aSAxel Dörfler if (max > gMaxRefresh) 96329e8a73aSAxel Dörfler max = gMaxRefresh; 96429e8a73aSAxel Dörfler 96570a2b1b5SAxel Dörfler monitor_info info; 96670a2b1b5SAxel Dörfler if (fScreenMode.GetMonitorInfo(info) == B_OK) { 96770a2b1b5SAxel Dörfler min = max_c(info.min_vertical_frequency, min); 96870a2b1b5SAxel Dörfler max = min_c(info.max_vertical_frequency, max); 96970a2b1b5SAxel Dörfler } 97070a2b1b5SAxel Dörfler 971c5d10f7aSAxel Dörfler RefreshWindow *fRefreshWindow = new RefreshWindow( 97270a2b1b5SAxel Dörfler fRefreshField->ConvertToScreen(B_ORIGIN), fSelected.refresh, 97370a2b1b5SAxel Dörfler min, max); 974a10cf76eSAxel Dörfler fRefreshWindow->Show(); 975a10cf76eSAxel Dörfler break; 976a10cf76eSAxel Dörfler } 977a10cf76eSAxel Dörfler 978a10cf76eSAxel Dörfler case SET_CUSTOM_REFRESH_MSG: 979a10cf76eSAxel Dörfler { 980a10cf76eSAxel Dörfler // user pressed "done" in "Other…" refresh dialog; 981a10cf76eSAxel Dörfler // select the refresh rate chosen 982a10cf76eSAxel Dörfler message->FindFloat("refresh", &fSelected.refresh); 983a10cf76eSAxel Dörfler 9845de171daSAxel Dörfler _UpdateRefreshControl(); 9855de171daSAxel Dörfler _CheckApplyEnabled(); 986a10cf76eSAxel Dörfler break; 987a10cf76eSAxel Dörfler } 988a10cf76eSAxel Dörfler 989a10cf76eSAxel Dörfler case POP_COMBINE_DISPLAYS_MSG: 990a10cf76eSAxel Dörfler { 991a10cf76eSAxel Dörfler // new combine mode has bee chosen 992a10cf76eSAxel Dörfler int32 mode; 993a10cf76eSAxel Dörfler if (message->FindInt32("mode", &mode) == B_OK) 994a10cf76eSAxel Dörfler fSelected.combine = (combine_mode)mode; 995a10cf76eSAxel Dörfler 9965de171daSAxel Dörfler _CheckResolutionMenu(); 9975de171daSAxel Dörfler _CheckApplyEnabled(); 998a10cf76eSAxel Dörfler break; 999a10cf76eSAxel Dörfler } 1000a10cf76eSAxel Dörfler 1001a10cf76eSAxel Dörfler case POP_SWAP_DISPLAYS_MSG: 1002a10cf76eSAxel Dörfler message->FindBool("swap", &fSelected.swap_displays); 10035de171daSAxel Dörfler _CheckApplyEnabled(); 1004a10cf76eSAxel Dörfler break; 1005a10cf76eSAxel Dörfler 1006a10cf76eSAxel Dörfler case POP_USE_LAPTOP_PANEL_MSG: 1007a10cf76eSAxel Dörfler message->FindBool("use", &fSelected.use_laptop_panel); 10085de171daSAxel Dörfler _CheckApplyEnabled(); 1009a10cf76eSAxel Dörfler break; 1010a10cf76eSAxel Dörfler 1011a10cf76eSAxel Dörfler case POP_TV_STANDARD_MSG: 1012a10cf76eSAxel Dörfler message->FindInt32("tv_standard", (int32 *)&fSelected.tv_standard); 10135de171daSAxel Dörfler _CheckApplyEnabled(); 1014a10cf76eSAxel Dörfler break; 1015a10cf76eSAxel Dörfler 1016df3f5bacSStephan Aßmus case BUTTON_LAUNCH_BACKGROUNDS_MSG: 10176f095d6aSRyan Leavengood if (be_roster->Launch(kBackgroundsSignature) == B_ALREADY_RUNNING) { 10186f095d6aSRyan Leavengood app_info info; 10196f095d6aSRyan Leavengood be_roster->GetAppInfo(kBackgroundsSignature, &info); 10206f095d6aSRyan Leavengood be_roster->ActivateApp(info.team); 10216f095d6aSRyan Leavengood } 1022df3f5bacSStephan Aßmus break; 1023df3f5bacSStephan Aßmus 1024a10cf76eSAxel Dörfler case BUTTON_DEFAULTS_MSG: 1025a10cf76eSAxel Dörfler { 10264be51fe3SWaldemar Kornewald // TODO: get preferred settings of screen 1027a10cf76eSAxel Dörfler fSelected.width = 640; 1028a10cf76eSAxel Dörfler fSelected.height = 480; 1029a10cf76eSAxel Dörfler fSelected.space = B_CMAP8; 1030a10cf76eSAxel Dörfler fSelected.refresh = 60.0; 1031a10cf76eSAxel Dörfler fSelected.combine = kCombineDisable; 1032a10cf76eSAxel Dörfler fSelected.swap_displays = false; 1033a10cf76eSAxel Dörfler fSelected.use_laptop_panel = false; 1034a10cf76eSAxel Dörfler fSelected.tv_standard = 0; 1035a10cf76eSAxel Dörfler 1036b21d610eSAxel Dörfler // TODO: workspace defaults 1037abc649b8SWaldemar Kornewald 10385de171daSAxel Dörfler _UpdateControls(); 1039a10cf76eSAxel Dörfler break; 1040a10cf76eSAxel Dörfler } 1041a10cf76eSAxel Dörfler 104210e9b12fSWaldemar Kornewald case BUTTON_UNDO_MSG: 104361c5c89bSAxel Dörfler fUndoScreenMode.Revert(); 10445de171daSAxel Dörfler _UpdateActiveMode(); 1045abc649b8SWaldemar Kornewald break; 1046abc649b8SWaldemar Kornewald 1047abc649b8SWaldemar Kornewald case BUTTON_REVERT_MSG: 1048abc649b8SWaldemar Kornewald { 1049abc649b8SWaldemar Kornewald fModified = false; 1050199893c3SAxel Dörfler fBootWorkspaceApplied = false; 1051abc649b8SWaldemar Kornewald 1052b21d610eSAxel Dörfler // ScreenMode::Revert() assumes that we first set the correct 1053b21d610eSAxel Dörfler // number of workspaces 1054b21d610eSAxel Dörfler 1055b21d610eSAxel Dörfler BPrivate::set_workspaces_layout(fOriginalWorkspacesColumns, 1056b21d610eSAxel Dörfler fOriginalWorkspacesRows); 1057b21d610eSAxel Dörfler _UpdateWorkspaceButtons(); 1058b21d610eSAxel Dörfler 1059a10cf76eSAxel Dörfler fScreenMode.Revert(); 10605de171daSAxel Dörfler _UpdateActiveMode(); 1061a10cf76eSAxel Dörfler break; 1062abc649b8SWaldemar Kornewald } 1063a10cf76eSAxel Dörfler 1064a10cf76eSAxel Dörfler case BUTTON_APPLY_MSG: 10655de171daSAxel Dörfler _Apply(); 1066a10cf76eSAxel Dörfler break; 1067a10cf76eSAxel Dörfler 1068abc649b8SWaldemar Kornewald case MAKE_INITIAL_MSG: 1069abc649b8SWaldemar Kornewald // user pressed "keep" in confirmation dialog 1070abc649b8SWaldemar Kornewald fModified = true; 10715de171daSAxel Dörfler _UpdateActiveMode(); 1072a10cf76eSAxel Dörfler break; 1073a10cf76eSAxel Dörfler 1074a10cf76eSAxel Dörfler default: 1075a10cf76eSAxel Dörfler BWindow::MessageReceived(message); 1076a10cf76eSAxel Dörfler break; 1077a10cf76eSAxel Dörfler } 1078a10cf76eSAxel Dörfler } 1079a10cf76eSAxel Dörfler 1080a10cf76eSAxel Dörfler 108112580984SAxel Dörfler status_t 108212580984SAxel Dörfler ScreenWindow::_WriteVesaModeFile(const screen_mode& mode) const 108312580984SAxel Dörfler { 108412580984SAxel Dörfler BPath path; 108512580984SAxel Dörfler status_t status = find_directory(B_USER_SETTINGS_DIRECTORY, &path, true); 108612580984SAxel Dörfler if (status < B_OK) 108712580984SAxel Dörfler return status; 108812580984SAxel Dörfler 108912580984SAxel Dörfler path.Append("kernel/drivers"); 109012580984SAxel Dörfler status = create_directory(path.Path(), 0755); 109112580984SAxel Dörfler if (status < B_OK) 109212580984SAxel Dörfler return status; 109312580984SAxel Dörfler 109412580984SAxel Dörfler path.Append("vesa"); 109512580984SAxel Dörfler BFile file; 109612580984SAxel Dörfler status = file.SetTo(path.Path(), B_CREATE_FILE | B_WRITE_ONLY | B_ERASE_FILE); 109712580984SAxel Dörfler if (status < B_OK) 109812580984SAxel Dörfler return status; 109912580984SAxel Dörfler 110012580984SAxel Dörfler char buffer[256]; 110112580984SAxel Dörfler snprintf(buffer, sizeof(buffer), "mode %ld %ld %ld\n", 110212580984SAxel Dörfler mode.width, mode.height, mode.BitsPerPixel()); 110312580984SAxel Dörfler 110412580984SAxel Dörfler ssize_t bytesWritten = file.Write(buffer, strlen(buffer)); 110512580984SAxel Dörfler if (bytesWritten < B_OK) 110612580984SAxel Dörfler return bytesWritten; 110712580984SAxel Dörfler 110812580984SAxel Dörfler return B_OK; 110912580984SAxel Dörfler } 111012580984SAxel Dörfler 111112580984SAxel Dörfler 1112b21d610eSAxel Dörfler BButton* 1113b21d610eSAxel Dörfler ScreenWindow::_CreateColumnRowButton(bool columns, bool plus) 1114b21d610eSAxel Dörfler { 1115b21d610eSAxel Dörfler BMessage* message = new BMessage(kMsgWorkspaceLayoutChanged); 1116b21d610eSAxel Dörfler message->AddInt32("delta_x", columns ? (plus ? 1 : -1) : 0); 1117b21d610eSAxel Dörfler message->AddInt32("delta_y", !columns ? (plus ? 1 : -1) : 0); 1118b21d610eSAxel Dörfler 1119b21d610eSAxel Dörfler BButton* button = new BButton(plus ? "+" : "-", message); 1120b21d610eSAxel Dörfler button->SetFontSize(be_plain_font->Size() * 0.9); 1121b21d610eSAxel Dörfler 1122b21d610eSAxel Dörfler BSize size = button->MinSize(); 1123b21d610eSAxel Dörfler size.width = button->StringWidth("+") + 16; 1124b21d610eSAxel Dörfler button->SetExplicitMinSize(size); 1125b21d610eSAxel Dörfler button->SetExplicitMaxSize(size); 1126b21d610eSAxel Dörfler 1127b21d610eSAxel Dörfler fWorkspacesButtons[(columns ? 0 : 2) + (plus ? 1 : 0)] = button; 1128b21d610eSAxel Dörfler return button; 1129b21d610eSAxel Dörfler } 1130b21d610eSAxel Dörfler 1131b21d610eSAxel Dörfler 1132b21d610eSAxel Dörfler BButton* 1133b21d610eSAxel Dörfler ScreenWindow::_GetColumnRowButton(bool columns, bool plus) 1134b21d610eSAxel Dörfler { 1135b21d610eSAxel Dörfler return fWorkspacesButtons[(columns ? 0 : 2) + (plus ? 1 : 0)]; 1136b21d610eSAxel Dörfler } 1137b21d610eSAxel Dörfler 1138b21d610eSAxel Dörfler 1139a10cf76eSAxel Dörfler void 11401fc4cb1fSAxel Dörfler ScreenWindow::_BuildSupportedColorSpaces() 11411fc4cb1fSAxel Dörfler { 11421fc4cb1fSAxel Dörfler fSupportedColorSpaces = 0; 11431fc4cb1fSAxel Dörfler 11441fc4cb1fSAxel Dörfler for (int32 i = 0; i < kColorSpaceCount; i++) { 11451fc4cb1fSAxel Dörfler for (int32 j = 0; j < fScreenMode.CountModes(); j++) { 11461fc4cb1fSAxel Dörfler if (fScreenMode.ModeAt(j).space == kColorSpaces[i].space) { 11471fc4cb1fSAxel Dörfler fSupportedColorSpaces |= 1 << i; 11481fc4cb1fSAxel Dörfler break; 11491fc4cb1fSAxel Dörfler } 11501fc4cb1fSAxel Dörfler } 11511fc4cb1fSAxel Dörfler } 11521fc4cb1fSAxel Dörfler } 11531fc4cb1fSAxel Dörfler 11541fc4cb1fSAxel Dörfler 11551fc4cb1fSAxel Dörfler void 11565de171daSAxel Dörfler ScreenWindow::_CheckApplyEnabled() 1157a10cf76eSAxel Dörfler { 115827c43a2dSRene Gollent fApplyButton->SetEnabled(fSelected != fActive 115927c43a2dSRene Gollent || fAllWorkspacesItem->IsMarked()); 1160b21d610eSAxel Dörfler 1161b21d610eSAxel Dörfler uint32 columns; 1162b21d610eSAxel Dörfler uint32 rows; 1163b21d610eSAxel Dörfler BPrivate::get_workspaces_layout(&columns, &rows); 1164b21d610eSAxel Dörfler 1165b21d610eSAxel Dörfler fRevertButton->SetEnabled(columns != fOriginalWorkspacesColumns 1166b21d610eSAxel Dörfler || rows != fOriginalWorkspacesRows 11675de171daSAxel Dörfler || fSelected != fOriginal); 1168a10cf76eSAxel Dörfler } 1169a10cf76eSAxel Dörfler 1170a10cf76eSAxel Dörfler 1171a10cf76eSAxel Dörfler void 11725de171daSAxel Dörfler ScreenWindow::_UpdateOriginal() 1173abc649b8SWaldemar Kornewald { 1174b21d610eSAxel Dörfler BPrivate::get_workspaces_layout(&fOriginalWorkspacesColumns, 1175b21d610eSAxel Dörfler &fOriginalWorkspacesRows); 1176b21d610eSAxel Dörfler 1177abc649b8SWaldemar Kornewald fScreenMode.Get(fOriginal); 1178abc649b8SWaldemar Kornewald fScreenMode.UpdateOriginalModes(); 1179abc649b8SWaldemar Kornewald } 1180abc649b8SWaldemar Kornewald 1181abc649b8SWaldemar Kornewald 1182abc649b8SWaldemar Kornewald void 118312966d04SAxel Dörfler ScreenWindow::_UpdateMonitor() 118412966d04SAxel Dörfler { 118512966d04SAxel Dörfler monitor_info info; 118612966d04SAxel Dörfler float diagonalInches; 118712966d04SAxel Dörfler status_t status = fScreenMode.GetMonitorInfo(info, &diagonalInches); 118855030977SAxel Dörfler if (status == B_OK) { 11891a8af605SAxel Dörfler char text[512]; 119066ab1666SAxel Dörfler snprintf(text, sizeof(text), "%s%s%s %g\"", info.vendor, 119166ab1666SAxel Dörfler info.name[0] ? " " : "", info.name, diagonalInches); 119212966d04SAxel Dörfler 119312966d04SAxel Dörfler fMonitorInfo->SetText(text); 119412966d04SAxel Dörfler 119512966d04SAxel Dörfler if (fMonitorInfo->IsHidden()) 119612966d04SAxel Dörfler fMonitorInfo->Show(); 119755030977SAxel Dörfler } else { 119855030977SAxel Dörfler if (!fMonitorInfo->IsHidden()) 119955030977SAxel Dörfler fMonitorInfo->Hide(); 120055030977SAxel Dörfler } 1201af8f9c31SAxel Dörfler 120255030977SAxel Dörfler char text[512]; 12031a8af605SAxel Dörfler size_t length = 0; 12041a8af605SAxel Dörfler text[0] = 0; 12051a8af605SAxel Dörfler 120655030977SAxel Dörfler if (status == B_OK) { 1207af8f9c31SAxel Dörfler if (info.min_horizontal_frequency != 0 1208af8f9c31SAxel Dörfler && info.min_vertical_frequency != 0 1209af8f9c31SAxel Dörfler && info.max_pixel_clock != 0) { 12101a8af605SAxel Dörfler length = snprintf(text, sizeof(text), 1211c9e8f97aSAdrien Destugues B_TRANSLATE("Horizonal frequency:\t%lu - %lu kHz\n" 12129c1a9b92SAdrien Destugues "Vertical frequency:\t%lu - %lu Hz\n\n" 1213c9e8f97aSAdrien Destugues "Maximum pixel clock:\t%g MHz"), 12141a8af605SAxel Dörfler info.min_horizontal_frequency, info.max_horizontal_frequency, 12151a8af605SAxel Dörfler info.min_vertical_frequency, info.max_vertical_frequency, 12161a8af605SAxel Dörfler info.max_pixel_clock / 1000.0); 1217af8f9c31SAxel Dörfler } 12181a8af605SAxel Dörfler if (info.serial_number[0] && length < sizeof(text)) { 12191a8af605SAxel Dörfler length += snprintf(text + length, sizeof(text) - length, 1220c9e8f97aSAdrien Destugues B_TRANSLATE("%sSerial no.: %s"), length ? "\n\n" : "", 12211a8af605SAxel Dörfler info.serial_number); 12221a8af605SAxel Dörfler if (info.produced.week != 0 && info.produced.year != 0 12231a8af605SAxel Dörfler && length < sizeof(text)) { 12241a8af605SAxel Dörfler length += snprintf(text + length, sizeof(text) - length, 12251a8af605SAxel Dörfler " (%u/%u)", info.produced.week, info.produced.year); 12261a8af605SAxel Dörfler } 12271a8af605SAxel Dörfler } 122855030977SAxel Dörfler } 122961c5c89bSAxel Dörfler 123061c5c89bSAxel Dörfler // Add info about the graphics device 123161c5c89bSAxel Dörfler 123261c5c89bSAxel Dörfler accelerant_device_info deviceInfo; 123361c5c89bSAxel Dörfler if (fScreenMode.GetDeviceInfo(deviceInfo) == B_OK 123461c5c89bSAxel Dörfler && length < sizeof(text)) { 123561c5c89bSAxel Dörfler if (deviceInfo.name[0] && deviceInfo.chipset[0]) { 123661c5c89bSAxel Dörfler length += snprintf(text + length, sizeof(text) - length, 123761c5c89bSAxel Dörfler "%s%s (%s)", length != 0 ? "\n\n" : "", deviceInfo.name, 123861c5c89bSAxel Dörfler deviceInfo.chipset); 123961c5c89bSAxel Dörfler } else if (deviceInfo.name[0] || deviceInfo.chipset[0]) { 124061c5c89bSAxel Dörfler length += snprintf(text + length, sizeof(text) - length, 124161c5c89bSAxel Dörfler "%s%s", length != 0 ? "\n\n" : "", deviceInfo.name[0] 124261c5c89bSAxel Dörfler ? deviceInfo.name : deviceInfo.chipset); 124361c5c89bSAxel Dörfler } 124461c5c89bSAxel Dörfler } 124561c5c89bSAxel Dörfler 12461a8af605SAxel Dörfler if (text[0]) 12471a8af605SAxel Dörfler fMonitorView->SetToolTip(text); 124812966d04SAxel Dörfler } 124912966d04SAxel Dörfler 125012966d04SAxel Dörfler 125112966d04SAxel Dörfler void 12521fc4cb1fSAxel Dörfler ScreenWindow::_UpdateColorLabel() 12531fc4cb1fSAxel Dörfler { 12541fc4cb1fSAxel Dörfler BString string; 1255551c9f15SSiarzhuk Zharski string << fSelected.BitsPerPixel() << " " << B_TRANSLATE("bits/pixel"); 12561fc4cb1fSAxel Dörfler fColorsMenu->Superitem()->SetLabel(string.String()); 12571fc4cb1fSAxel Dörfler } 12581fc4cb1fSAxel Dörfler 12591fc4cb1fSAxel Dörfler 12601fc4cb1fSAxel Dörfler void 12615de171daSAxel Dörfler ScreenWindow::_Apply() 1262a10cf76eSAxel Dörfler { 1263abc649b8SWaldemar Kornewald // make checkpoint, so we can undo these changes 126461c5c89bSAxel Dörfler fUndoScreenMode.UpdateOriginalModes(); 126561c5c89bSAxel Dörfler 126607184a9eSAxel Dörfler status_t status = fScreenMode.Set(fSelected); 126707184a9eSAxel Dörfler if (status == B_OK) { 1268abc649b8SWaldemar Kornewald // use the mode that has eventually been set and 1269abc649b8SWaldemar Kornewald // thus we know to be working; it can differ from 1270abc649b8SWaldemar Kornewald // the mode selected by user due to hardware limitation 1271abc649b8SWaldemar Kornewald display_mode newMode; 1272abc649b8SWaldemar Kornewald BScreen screen(this); 1273abc649b8SWaldemar Kornewald screen.GetMode(&newMode); 1274abc649b8SWaldemar Kornewald 1275abc649b8SWaldemar Kornewald if (fAllWorkspacesItem->IsMarked()) { 1276abc649b8SWaldemar Kornewald int32 originatingWorkspace = current_workspace(); 1277abc649b8SWaldemar Kornewald for (int32 i = 0; i < count_workspaces(); i++) { 1278abc649b8SWaldemar Kornewald if (i != originatingWorkspace) 1279abc649b8SWaldemar Kornewald screen.SetMode(i, &newMode, true); 1280abc649b8SWaldemar Kornewald } 1281199893c3SAxel Dörfler fBootWorkspaceApplied = true; 1282199893c3SAxel Dörfler } else { 1283199893c3SAxel Dörfler if (current_workspace() == 0) 1284199893c3SAxel Dörfler fBootWorkspaceApplied = true; 1285abc649b8SWaldemar Kornewald } 1286abc649b8SWaldemar Kornewald 1287a10cf76eSAxel Dörfler fActive = fSelected; 1288a10cf76eSAxel Dörfler 1289abc649b8SWaldemar Kornewald // TODO: only show alert when this is an unknown mode 1290a10cf76eSAxel Dörfler BWindow* window = new AlertWindow(this); 1291a10cf76eSAxel Dörfler window->Show(); 129207184a9eSAxel Dörfler } else { 129307184a9eSAxel Dörfler char message[256]; 129407184a9eSAxel Dörfler snprintf(message, sizeof(message), 1295c9e8f97aSAdrien Destugues B_TRANSLATE("The screen mode could not be set:\n\t%s\n"), 1296c9e8f97aSAdrien Destugues screen_errors(status)); 1297551c9f15SSiarzhuk Zharski BAlert* alert = new BAlert(B_TRANSLATE("Warning"), message, 1298c9e8f97aSAdrien Destugues B_TRANSLATE("OK"), NULL, NULL, 129907184a9eSAxel Dörfler B_WIDTH_AS_USUAL, B_WARNING_ALERT); 130007184a9eSAxel Dörfler alert->Go(); 1301a10cf76eSAxel Dörfler } 130207184a9eSAxel Dörfler } 130307184a9eSAxel Dörfler 1304