1a10cf76eSAxel Dörfler /* 210dfe897SAxel 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), 171*3f953a72SAxel Dörfler fIsVesa(false), 172199893c3SAxel Dörfler fBootWorkspaceApplied(false), 173a10cf76eSAxel Dörfler fScreenMode(this), 17461c5c89bSAxel Dörfler fUndoScreenMode(this), 175abc649b8SWaldemar Kornewald fModified(false) 176a10cf76eSAxel Dörfler { 177a10cf76eSAxel Dörfler BScreen screen(this); 178a10cf76eSAxel Dörfler 17912580984SAxel Dörfler accelerant_device_info info; 180d1516993SAxel Dörfler if (screen.GetDeviceInfo(&info) == B_OK 181d1516993SAxel Dörfler && !strcasecmp(info.chipset, "VESA")) 18212580984SAxel Dörfler fIsVesa = true; 18312580984SAxel Dörfler 1845de171daSAxel Dörfler _UpdateOriginal(); 1851fc4cb1fSAxel Dörfler _BuildSupportedColorSpaces(); 186a10cf76eSAxel Dörfler fActive = fSelected = fOriginal; 187a10cf76eSAxel Dörfler 1885a78744bSAxel Dörfler fSettings = settings; 1895a78744bSAxel Dörfler 1905a78744bSAxel Dörfler // we need the "Current Workspace" first to get its height 1915a78744bSAxel Dörfler 192c9e8f97aSAdrien Destugues BPopUpMenu *popUpMenu = new BPopUpMenu(B_TRANSLATE("Current workspace"), 193c9e8f97aSAdrien Destugues true, true); 194c9e8f97aSAdrien Destugues fAllWorkspacesItem = new BMenuItem(B_TRANSLATE("All workspaces"), 195d1516993SAxel Dörfler new BMessage(WORKSPACE_CHECK_MSG)); 1965a78744bSAxel Dörfler popUpMenu->AddItem(fAllWorkspacesItem); 197c9e8f97aSAdrien Destugues BMenuItem *item = new BMenuItem(B_TRANSLATE("Current workspace"), 198d1516993SAxel Dörfler new BMessage(WORKSPACE_CHECK_MSG)); 199b72c4836SAlexandre Deckner 2005a78744bSAxel Dörfler popUpMenu->AddItem(item); 20127c43a2dSRene Gollent fAllWorkspacesItem->SetMarked(true); 2025a78744bSAxel Dörfler 203b21d610eSAxel Dörfler BMenuField* workspaceMenuField = new BMenuField("WorkspaceMenu", NULL, 20410dfe897SAxel Dörfler popUpMenu); 2055a78744bSAxel Dörfler workspaceMenuField->ResizeToPreferred(); 206a10cf76eSAxel Dörfler 207a10cf76eSAxel Dörfler // box on the left with workspace count and monitor view 208a10cf76eSAxel Dörfler 209b21d610eSAxel Dörfler BBox* screenBox = new BBox("screen box"); 2108bf23e3cSAxel Dörfler BGroupLayout* layout = new BGroupLayout(B_VERTICAL, 5.0); 211b21d610eSAxel Dörfler layout->SetInsets(10, 10, 10, 10); 212b21d610eSAxel Dörfler screenBox->SetLayout(layout); 213a10cf76eSAxel Dörfler 21412966d04SAxel Dörfler fMonitorInfo = new BStringView("monitor info", ""); 21512966d04SAxel Dörfler screenBox->AddChild(fMonitorInfo); 21612966d04SAxel Dörfler 217c9e8f97aSAdrien Destugues fMonitorView = new MonitorView(BRect(0.0, 0.0, 80.0, 80.0), 218551c9f15SSiarzhuk Zharski "monitor", screen.Frame().IntegerWidth() + 1, 219c9e8f97aSAdrien Destugues screen.Frame().IntegerHeight() + 1); 220b21d610eSAxel Dörfler screenBox->AddChild(fMonitorView); 2215a78744bSAxel Dörfler 222c9e8f97aSAdrien Destugues fColumnsControl = new BTextControl(B_TRANSLATE("Columns:"), "0", 223b21d610eSAxel Dörfler new BMessage(kMsgWorkspaceColumnsChanged)); 224c9e8f97aSAdrien Destugues fRowsControl = new BTextControl(B_TRANSLATE("Rows:"), "0", 225b21d610eSAxel Dörfler new BMessage(kMsgWorkspaceRowsChanged)); 226b21d610eSAxel Dörfler 227b21d610eSAxel Dörfler screenBox->AddChild(BLayoutBuilder::Grid<>(5.0, 5.0) 228c9e8f97aSAdrien Destugues .Add(new BStringView("", B_TRANSLATE("Workspaces")), 0, 0, 3) 229b21d610eSAxel Dörfler .AddTextControl(fColumnsControl, 0, 1, B_ALIGN_RIGHT) 230b21d610eSAxel Dörfler .AddGroup(B_HORIZONTAL, 0, 2, 1) 231b21d610eSAxel Dörfler .Add(_CreateColumnRowButton(true, false)) 232b21d610eSAxel Dörfler .Add(_CreateColumnRowButton(true, true)) 233b21d610eSAxel Dörfler .End() 234b21d610eSAxel Dörfler .AddTextControl(fRowsControl, 0, 2, B_ALIGN_RIGHT) 235b21d610eSAxel Dörfler .AddGroup(B_HORIZONTAL, 0, 2, 2) 236b21d610eSAxel Dörfler .Add(_CreateColumnRowButton(false, false)) 237b21d610eSAxel Dörfler .Add(_CreateColumnRowButton(false, true)) 23825fd5c7bSAlex Wilson .End() 23925fd5c7bSAlex Wilson .View()); 240b21d610eSAxel Dörfler 241b21d610eSAxel Dörfler fBackgroundsButton = new BButton("BackgroundsButton", 242c9e8f97aSAdrien Destugues B_TRANSLATE("Set background" B_UTF8_ELLIPSIS), 243b21d610eSAxel Dörfler new BMessage(BUTTON_LAUNCH_BACKGROUNDS_MSG)); 244b21d610eSAxel Dörfler fBackgroundsButton->SetFontSize(be_plain_font->Size() * 0.9); 245b21d610eSAxel Dörfler screenBox->AddChild(fBackgroundsButton); 246a10cf76eSAxel Dörfler 247a10cf76eSAxel Dörfler // box on the right with screen resolution, etc. 248a10cf76eSAxel Dörfler 249b21d610eSAxel Dörfler BBox* controlsBox = new BBox("controls box"); 250b21d610eSAxel Dörfler controlsBox->SetLabel(workspaceMenuField); 25125fd5c7bSAlex Wilson BGroupView* outerControlsView = new BGroupView(B_VERTICAL, 10.0); 25225fd5c7bSAlex Wilson outerControlsView->GroupLayout()->SetInsets(10, 10, 10, 10); 253b21d610eSAxel Dörfler controlsBox->AddChild(outerControlsView); 254a10cf76eSAxel Dörfler 255551c9f15SSiarzhuk Zharski fResolutionMenu = new BPopUpMenu("resolution", true, true); 256a10cf76eSAxel Dörfler 25766ab1666SAxel Dörfler uint16 maxWidth = 0; 25866ab1666SAxel Dörfler uint16 maxHeight = 0; 25966ab1666SAxel Dörfler uint16 previousWidth = 0; 26066ab1666SAxel Dörfler uint16 previousHeight = 0; 261a10cf76eSAxel Dörfler for (int32 i = 0; i < fScreenMode.CountModes(); i++) { 262a10cf76eSAxel Dörfler screen_mode mode = fScreenMode.ModeAt(i); 263a10cf76eSAxel Dörfler 264a10cf76eSAxel Dörfler if (mode.width == previousWidth && mode.height == previousHeight) 265a10cf76eSAxel Dörfler continue; 266a10cf76eSAxel Dörfler 267a10cf76eSAxel Dörfler previousWidth = mode.width; 268a10cf76eSAxel Dörfler previousHeight = mode.height; 26966ab1666SAxel Dörfler if (maxWidth < mode.width) 27066ab1666SAxel Dörfler maxWidth = mode.width; 27166ab1666SAxel Dörfler if (maxHeight < mode.height) 27266ab1666SAxel Dörfler maxHeight = mode.height; 273a10cf76eSAxel Dörfler 274a10cf76eSAxel Dörfler BMessage* message = new BMessage(POP_RESOLUTION_MSG); 275a10cf76eSAxel Dörfler message->AddInt32("width", mode.width); 276a10cf76eSAxel Dörfler message->AddInt32("height", mode.height); 277a10cf76eSAxel Dörfler 278a10cf76eSAxel Dörfler BString name; 279a10cf76eSAxel Dörfler name << mode.width << " x " << mode.height; 280a10cf76eSAxel Dörfler 281a10cf76eSAxel Dörfler fResolutionMenu->AddItem(new BMenuItem(name.String(), message)); 282a10cf76eSAxel Dörfler } 283a10cf76eSAxel Dörfler 28466ab1666SAxel Dörfler fMonitorView->SetMaxResolution(maxWidth, maxHeight); 28566ab1666SAxel Dörfler 286c9e8f97aSAdrien Destugues fResolutionField = new BMenuField("ResolutionMenu", 28710dfe897SAxel Dörfler B_TRANSLATE("Resolution:"), fResolutionMenu); 288a10cf76eSAxel Dörfler 289551c9f15SSiarzhuk Zharski fColorsMenu = new BPopUpMenu("colors", true, false); 290a10cf76eSAxel Dörfler 291a10cf76eSAxel Dörfler for (int32 i = 0; i < kColorSpaceCount; i++) { 2921fc4cb1fSAxel Dörfler if ((fSupportedColorSpaces & (1 << i)) == 0) 2931fc4cb1fSAxel Dörfler continue; 2941fc4cb1fSAxel Dörfler 295a10cf76eSAxel Dörfler BMessage* message = new BMessage(POP_COLORS_MSG); 296a10cf76eSAxel Dörfler message->AddInt32("bits_per_pixel", kColorSpaces[i].bits_per_pixel); 297a10cf76eSAxel Dörfler message->AddInt32("space", kColorSpaces[i].space); 298a10cf76eSAxel Dörfler 2991fc4cb1fSAxel Dörfler BMenuItem* item = new BMenuItem(kColorSpaces[i].label, message); 3001fc4cb1fSAxel Dörfler if (kColorSpaces[i].space == screen.ColorSpace()) 3011fc4cb1fSAxel Dörfler fUserSelectedColorSpace = item; 3021fc4cb1fSAxel Dörfler 3031fc4cb1fSAxel Dörfler fColorsMenu->AddItem(item); 304a10cf76eSAxel Dörfler } 305a10cf76eSAxel Dörfler 306c9e8f97aSAdrien Destugues fColorsField = new BMenuField("ColorsMenu", B_TRANSLATE("Colors:"), 30710dfe897SAxel Dörfler fColorsMenu); 308a10cf76eSAxel Dörfler 309551c9f15SSiarzhuk Zharski fRefreshMenu = new BPopUpMenu("refresh rate", true, true); 310a10cf76eSAxel Dörfler 31129e8a73aSAxel Dörfler BMessage *message; 31229e8a73aSAxel 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; 318551c9f15SSiarzhuk Zharski name << min << " " << B_TRANSLATE("Hz"); 31929e8a73aSAxel Dörfler 32029e8a73aSAxel Dörfler message = new BMessage(POP_REFRESH_MSG); 32129e8a73aSAxel Dörfler message->AddFloat("refresh", min); 32229e8a73aSAxel Dörfler 32329e8a73aSAxel Dörfler fRefreshMenu->AddItem(item = new BMenuItem(name.String(), message)); 32429e8a73aSAxel Dörfler item->SetEnabled(false); 32529e8a73aSAxel Dörfler } else { 32670a2b1b5SAxel Dörfler monitor_info info; 32770a2b1b5SAxel Dörfler if (fScreenMode.GetMonitorInfo(info) == B_OK) { 32870a2b1b5SAxel Dörfler min = max_c(info.min_vertical_frequency, min); 32970a2b1b5SAxel Dörfler max = min_c(info.max_vertical_frequency, max); 33070a2b1b5SAxel Dörfler } 33170a2b1b5SAxel Dörfler 332a10cf76eSAxel Dörfler for (int32 i = 0; i < kRefreshRateCount; ++i) { 33370a2b1b5SAxel Dörfler if (kRefreshRates[i] < min || kRefreshRates[i] > max) 33470a2b1b5SAxel Dörfler continue; 33570a2b1b5SAxel Dörfler 336a10cf76eSAxel Dörfler BString name; 337551c9f15SSiarzhuk Zharski name << kRefreshRates[i] << " " << B_TRANSLATE("Hz"); 338a10cf76eSAxel Dörfler 33929e8a73aSAxel Dörfler message = new BMessage(POP_REFRESH_MSG); 340a10cf76eSAxel Dörfler message->AddFloat("refresh", kRefreshRates[i]); 341a10cf76eSAxel Dörfler 342a10cf76eSAxel Dörfler fRefreshMenu->AddItem(new BMenuItem(name.String(), message)); 343a10cf76eSAxel Dörfler } 344a10cf76eSAxel Dörfler 34529e8a73aSAxel Dörfler message = new BMessage(POP_OTHER_REFRESH_MSG); 346a10cf76eSAxel Dörfler 347c9e8f97aSAdrien Destugues fOtherRefresh = new BMenuItem(B_TRANSLATE("Other" B_UTF8_ELLIPSIS), 348c9e8f97aSAdrien Destugues message); 349a10cf76eSAxel Dörfler fRefreshMenu->AddItem(fOtherRefresh); 35029e8a73aSAxel Dörfler } 351a10cf76eSAxel Dörfler 352c9e8f97aSAdrien Destugues fRefreshField = new BMenuField("RefreshMenu", B_TRANSLATE("Refresh rate:"), 35310dfe897SAxel Dörfler fRefreshMenu); 354b21d610eSAxel Dörfler 35512580984SAxel Dörfler if (_IsVesa()) 35612580984SAxel Dörfler fRefreshField->Hide(); 357a10cf76eSAxel Dörfler 358a10cf76eSAxel Dörfler // enlarged area for multi-monitor settings 359a10cf76eSAxel Dörfler { 360a10cf76eSAxel Dörfler bool dummy; 361a10cf76eSAxel Dörfler uint32 dummy32; 362a10cf76eSAxel Dörfler bool multiMonSupport; 363a10cf76eSAxel Dörfler bool useLaptopPanelSupport; 364a10cf76eSAxel Dörfler bool tvStandardSupport; 365a10cf76eSAxel Dörfler 366a10cf76eSAxel Dörfler multiMonSupport = TestMultiMonSupport(&screen) == B_OK; 367a10cf76eSAxel Dörfler useLaptopPanelSupport = GetUseLaptopPanel(&screen, &dummy) == B_OK; 368a10cf76eSAxel Dörfler tvStandardSupport = GetTVStandard(&screen, &dummy32) == B_OK; 369a10cf76eSAxel Dörfler 370a10cf76eSAxel Dörfler // even if there is no support, we still create all controls 371a10cf76eSAxel Dörfler // to make sure we don't access NULL pointers later on 372a10cf76eSAxel Dörfler 373551c9f15SSiarzhuk Zharski fCombineMenu = new BPopUpMenu("CombineDisplays", 374c9e8f97aSAdrien Destugues true, true); 375a10cf76eSAxel Dörfler 376a10cf76eSAxel Dörfler for (int32 i = 0; i < kCombineModeCount; i++) { 377a10cf76eSAxel Dörfler message = new BMessage(POP_COMBINE_DISPLAYS_MSG); 378a10cf76eSAxel Dörfler message->AddInt32("mode", kCombineModes[i].mode); 379a10cf76eSAxel Dörfler 380d1516993SAxel Dörfler fCombineMenu->AddItem(new BMenuItem(kCombineModes[i].name, 381d1516993SAxel Dörfler message)); 382a10cf76eSAxel Dörfler } 383a10cf76eSAxel Dörfler 384b21d610eSAxel Dörfler fCombineField = new BMenuField("CombineMenu", 38510dfe897SAxel Dörfler B_TRANSLATE("Combine displays:"), fCombineMenu); 386a10cf76eSAxel Dörfler 387a10cf76eSAxel Dörfler if (!multiMonSupport) 388df3f5bacSStephan Aßmus fCombineField->Hide(); 389a10cf76eSAxel Dörfler 390551c9f15SSiarzhuk Zharski fSwapDisplaysMenu = new BPopUpMenu("SwapDisplays", 391c9e8f97aSAdrien Destugues true, true); 392a10cf76eSAxel Dörfler 393a10cf76eSAxel Dörfler // !order is important - we rely that boolean value == idx 394a10cf76eSAxel Dörfler message = new BMessage(POP_SWAP_DISPLAYS_MSG); 395a10cf76eSAxel Dörfler message->AddBool("swap", false); 396c9e8f97aSAdrien Destugues fSwapDisplaysMenu->AddItem(new BMenuItem(B_TRANSLATE("no"), message)); 397a10cf76eSAxel Dörfler 398a10cf76eSAxel Dörfler message = new BMessage(POP_SWAP_DISPLAYS_MSG); 399a10cf76eSAxel Dörfler message->AddBool("swap", true); 400c9e8f97aSAdrien Destugues fSwapDisplaysMenu->AddItem(new BMenuItem(B_TRANSLATE("yes"), message)); 401a10cf76eSAxel Dörfler 402c9e8f97aSAdrien Destugues fSwapDisplaysField = new BMenuField("SwapMenu", 40310dfe897SAxel Dörfler B_TRANSLATE("Swap displays:"), fSwapDisplaysMenu); 404a10cf76eSAxel Dörfler 405a10cf76eSAxel Dörfler if (!multiMonSupport) 406df3f5bacSStephan Aßmus fSwapDisplaysField->Hide(); 407a10cf76eSAxel Dörfler 408551c9f15SSiarzhuk Zharski fUseLaptopPanelMenu = new BPopUpMenu("UseLaptopPanel", 409c9e8f97aSAdrien Destugues true, true); 410a10cf76eSAxel Dörfler 411a10cf76eSAxel Dörfler // !order is important - we rely that boolean value == idx 412a10cf76eSAxel Dörfler message = new BMessage(POP_USE_LAPTOP_PANEL_MSG); 413a10cf76eSAxel Dörfler message->AddBool("use", false); 414c9e8f97aSAdrien Destugues fUseLaptopPanelMenu->AddItem(new BMenuItem(B_TRANSLATE("if needed"), 415c9e8f97aSAdrien Destugues message)); 416a10cf76eSAxel Dörfler 417a10cf76eSAxel Dörfler message = new BMessage(POP_USE_LAPTOP_PANEL_MSG); 418a10cf76eSAxel Dörfler message->AddBool("use", true); 419c9e8f97aSAdrien Destugues fUseLaptopPanelMenu->AddItem(new BMenuItem(B_TRANSLATE("always"), 420c9e8f97aSAdrien Destugues message)); 421a10cf76eSAxel Dörfler 422b21d610eSAxel Dörfler fUseLaptopPanelField = new BMenuField("UseLaptopPanel", 42310dfe897SAxel Dörfler B_TRANSLATE("Use laptop panel:"), fUseLaptopPanelMenu); 424a10cf76eSAxel Dörfler 425a10cf76eSAxel Dörfler if (!useLaptopPanelSupport) 426df3f5bacSStephan Aßmus fUseLaptopPanelField->Hide(); 427a10cf76eSAxel Dörfler 428551c9f15SSiarzhuk Zharski fTVStandardMenu = new BPopUpMenu("TVStandard", true, true); 429a10cf76eSAxel Dörfler 430a10cf76eSAxel Dörfler // arbitrary limit 431a10cf76eSAxel Dörfler uint32 i; 432a10cf76eSAxel Dörfler for (i = 0; i < 100; ++i) { 433a10cf76eSAxel Dörfler uint32 mode; 434a10cf76eSAxel Dörfler if (GetNthSupportedTVStandard(&screen, i, &mode) != B_OK) 435a10cf76eSAxel Dörfler break; 436a10cf76eSAxel Dörfler 437a10cf76eSAxel Dörfler BString name = tv_standard_to_string(mode); 438a10cf76eSAxel Dörfler 439a10cf76eSAxel Dörfler message = new BMessage(POP_TV_STANDARD_MSG); 440a10cf76eSAxel Dörfler message->AddInt32("tv_standard", mode); 441a10cf76eSAxel Dörfler 442a10cf76eSAxel Dörfler fTVStandardMenu->AddItem(new BMenuItem(name.String(), message)); 443a10cf76eSAxel Dörfler } 444a10cf76eSAxel Dörfler 445c9e8f97aSAdrien Destugues fTVStandardField = new BMenuField("tv standard", 44610dfe897SAxel Dörfler B_TRANSLATE("Video format:"), fTVStandardMenu); 447df3f5bacSStephan Aßmus fTVStandardField->SetAlignment(B_ALIGN_RIGHT); 448a10cf76eSAxel Dörfler 449b21d610eSAxel Dörfler if (!tvStandardSupport || i == 0) 450df3f5bacSStephan Aßmus fTVStandardField->Hide(); 451a10cf76eSAxel Dörfler } 452a10cf76eSAxel Dörfler 45325fd5c7bSAlex Wilson BLayoutBuilder::Group<>(outerControlsView) 45425fd5c7bSAlex Wilson .AddGrid(5.0, 5.0) 455b21d610eSAxel Dörfler .AddMenuField(fResolutionField, 0, 0, B_ALIGN_RIGHT) 456b21d610eSAxel Dörfler .AddMenuField(fColorsField, 0, 1, B_ALIGN_RIGHT) 457b21d610eSAxel Dörfler .AddMenuField(fRefreshField, 0, 2, B_ALIGN_RIGHT) 458b21d610eSAxel Dörfler .AddMenuField(fCombineField, 0, 3, B_ALIGN_RIGHT) 459b21d610eSAxel Dörfler .AddMenuField(fSwapDisplaysField, 0, 4, B_ALIGN_RIGHT) 460b21d610eSAxel Dörfler .AddMenuField(fUseLaptopPanelField, 0, 5, B_ALIGN_RIGHT) 46125fd5c7bSAlex Wilson .AddMenuField(fTVStandardField, 0, 6, B_ALIGN_RIGHT) 46225fd5c7bSAlex Wilson .End(); 463df3f5bacSStephan Aßmus 464abc649b8SWaldemar Kornewald // TODO: we don't support getting the screen's preferred settings 465abc649b8SWaldemar Kornewald /* fDefaultsButton = new BButton(buttonRect, "DefaultsButton", "Defaults", 466b21d610eSAxel Dörfler new BMessage(BUTTON_DEFAULTS_MSG));*/ 467a10cf76eSAxel Dörfler 468c9e8f97aSAdrien Destugues fApplyButton = new BButton("ApplyButton", B_TRANSLATE("Apply"), 469df3f5bacSStephan Aßmus new BMessage(BUTTON_APPLY_MSG)); 470df3f5bacSStephan Aßmus fApplyButton->SetEnabled(false); 47125fd5c7bSAlex Wilson BLayoutBuilder::Group<>(outerControlsView) 472b21d610eSAxel Dörfler .AddGlue() 47325fd5c7bSAlex Wilson .AddGroup(B_HORIZONTAL) 47425fd5c7bSAlex Wilson .AddGlue() 47525fd5c7bSAlex Wilson .Add(fApplyButton); 476b21d610eSAxel Dörfler 477c9e8f97aSAdrien Destugues fRevertButton = new BButton("RevertButton", B_TRANSLATE("Revert"), 478b21d610eSAxel Dörfler new BMessage(BUTTON_REVERT_MSG)); 479b21d610eSAxel Dörfler fRevertButton->SetEnabled(false); 480b21d610eSAxel Dörfler 48125fd5c7bSAlex Wilson BLayoutBuilder::Group<>(this, B_VERTICAL, 10.0) 482b21d610eSAxel Dörfler .SetInsets(10, 10, 10, 10) 483b21d610eSAxel Dörfler .AddGroup(B_HORIZONTAL, 10.0) 484b21d610eSAxel Dörfler .AddGroup(B_VERTICAL) 48525fd5c7bSAlex Wilson .AddStrut(controlsBox->TopBorderOffset() - 1) 486b21d610eSAxel Dörfler .Add(screenBox) 487b21d610eSAxel Dörfler .End() 488b21d610eSAxel Dörfler .Add(controlsBox) 489b21d610eSAxel Dörfler .End() 490b21d610eSAxel Dörfler .AddGroup(B_HORIZONTAL, 10.0) 491b21d610eSAxel Dörfler .Add(fRevertButton) 492b21d610eSAxel Dörfler .AddGlue(); 493b21d610eSAxel Dörfler 4945de171daSAxel Dörfler _UpdateControls(); 49512966d04SAxel Dörfler _UpdateMonitor(); 496a10cf76eSAxel Dörfler } 497a10cf76eSAxel Dörfler 498a10cf76eSAxel Dörfler 499a10cf76eSAxel Dörfler ScreenWindow::~ScreenWindow() 500a10cf76eSAxel Dörfler { 501a10cf76eSAxel Dörfler delete fSettings; 502a10cf76eSAxel Dörfler } 503a10cf76eSAxel Dörfler 504a10cf76eSAxel Dörfler 505a10cf76eSAxel Dörfler bool 506a10cf76eSAxel Dörfler ScreenWindow::QuitRequested() 507a10cf76eSAxel Dörfler { 508a10cf76eSAxel Dörfler fSettings->SetWindowFrame(Frame()); 509199893c3SAxel Dörfler 510199893c3SAxel Dörfler // Write mode of workspace 0 (the boot workspace) to the vesa settings file 511199893c3SAxel Dörfler screen_mode vesaMode; 512199893c3SAxel Dörfler if (fBootWorkspaceApplied && fScreenMode.Get(vesaMode, 0) == B_OK) { 513199893c3SAxel Dörfler status_t status = _WriteVesaModeFile(vesaMode); 51412580984SAxel Dörfler if (status < B_OK) { 515c9e8f97aSAdrien Destugues BString warning = B_TRANSLATE("Could not write VESA mode settings" 516c9e8f97aSAdrien Destugues " file:\n\t"); 51712580984SAxel Dörfler warning << strerror(status); 518551c9f15SSiarzhuk Zharski (new BAlert(B_TRANSLATE("Warning"), warning.String(), B_TRANSLATE("OK"), NULL, 519c9e8f97aSAdrien Destugues NULL, B_WIDTH_AS_USUAL, B_WARNING_ALERT))->Go(); 52012580984SAxel Dörfler } 52112580984SAxel Dörfler } 52212580984SAxel Dörfler 523a10cf76eSAxel Dörfler be_app->PostMessage(B_QUIT_REQUESTED); 524a10cf76eSAxel Dörfler 525a10cf76eSAxel Dörfler return BWindow::QuitRequested(); 526a10cf76eSAxel Dörfler } 527a10cf76eSAxel Dörfler 528a10cf76eSAxel Dörfler 5295de171daSAxel Dörfler /*! Update resolution list according to combine mode 5301fc4cb1fSAxel Dörfler (some resolutions may not be combinable due to memory restrictions). 531a10cf76eSAxel Dörfler */ 532a10cf76eSAxel Dörfler void 5335de171daSAxel Dörfler ScreenWindow::_CheckResolutionMenu() 534a10cf76eSAxel Dörfler { 535a10cf76eSAxel Dörfler for (int32 i = 0; i < fResolutionMenu->CountItems(); i++) 536a10cf76eSAxel Dörfler fResolutionMenu->ItemAt(i)->SetEnabled(false); 537a10cf76eSAxel Dörfler 538a10cf76eSAxel Dörfler for (int32 i = 0; i < fScreenMode.CountModes(); i++) { 539a10cf76eSAxel Dörfler screen_mode mode = fScreenMode.ModeAt(i); 540a10cf76eSAxel Dörfler if (mode.combine != fSelected.combine) 541a10cf76eSAxel Dörfler continue; 542a10cf76eSAxel Dörfler 543a10cf76eSAxel Dörfler BString name; 544a10cf76eSAxel Dörfler name << mode.width << " x " << mode.height; 545a10cf76eSAxel Dörfler 546a10cf76eSAxel Dörfler BMenuItem *item = fResolutionMenu->FindItem(name.String()); 547a10cf76eSAxel Dörfler if (item != NULL) 548a10cf76eSAxel Dörfler item->SetEnabled(true); 549a10cf76eSAxel Dörfler } 550a10cf76eSAxel Dörfler } 551a10cf76eSAxel Dörfler 552a10cf76eSAxel Dörfler 5535de171daSAxel Dörfler /*! Update color and refresh options according to current mode 5545de171daSAxel Dörfler (a color space is made active if there is any mode with 5555de171daSAxel Dörfler given resolution and this colour space; same applies for 5565de171daSAxel Dörfler refresh rate, though "Other…" is always possible) 557a10cf76eSAxel Dörfler */ 558a10cf76eSAxel Dörfler void 5595de171daSAxel Dörfler ScreenWindow::_CheckColorMenu() 560a10cf76eSAxel Dörfler { 5611fc4cb1fSAxel Dörfler int32 supportsAnything = false; 5621fc4cb1fSAxel Dörfler int32 index = 0; 5631fc4cb1fSAxel Dörfler 564a10cf76eSAxel Dörfler for (int32 i = 0; i < kColorSpaceCount; i++) { 5651fc4cb1fSAxel Dörfler if ((fSupportedColorSpaces & (1 << i)) == 0) 5661fc4cb1fSAxel Dörfler continue; 5671fc4cb1fSAxel Dörfler 568a10cf76eSAxel Dörfler bool supported = false; 569a10cf76eSAxel Dörfler 570a10cf76eSAxel Dörfler for (int32 j = 0; j < fScreenMode.CountModes(); j++) { 571a10cf76eSAxel Dörfler screen_mode mode = fScreenMode.ModeAt(j); 572a10cf76eSAxel Dörfler 573a10cf76eSAxel Dörfler if (fSelected.width == mode.width 574a10cf76eSAxel Dörfler && fSelected.height == mode.height 5751fc4cb1fSAxel Dörfler && kColorSpaces[i].space == mode.space 576a10cf76eSAxel Dörfler && fSelected.combine == mode.combine) { 5771fc4cb1fSAxel Dörfler supportsAnything = true; 578a10cf76eSAxel Dörfler supported = true; 579a10cf76eSAxel Dörfler break; 580a10cf76eSAxel Dörfler } 581a10cf76eSAxel Dörfler } 582a10cf76eSAxel Dörfler 5831fc4cb1fSAxel Dörfler BMenuItem* item = fColorsMenu->ItemAt(index++); 584a10cf76eSAxel Dörfler if (item) 585a10cf76eSAxel Dörfler item->SetEnabled(supported); 586a10cf76eSAxel Dörfler } 5871fc4cb1fSAxel Dörfler 5881fc4cb1fSAxel Dörfler fColorsField->SetEnabled(supportsAnything); 5891fc4cb1fSAxel Dörfler 5901fc4cb1fSAxel Dörfler if (!supportsAnything) 5911fc4cb1fSAxel Dörfler return; 5921fc4cb1fSAxel Dörfler 5931fc4cb1fSAxel Dörfler // Make sure a valid item is selected 5941fc4cb1fSAxel Dörfler 5951fc4cb1fSAxel Dörfler BMenuItem* item = fColorsMenu->FindMarked(); 5961fc4cb1fSAxel Dörfler bool changed = false; 5971fc4cb1fSAxel Dörfler 5981fc4cb1fSAxel Dörfler if (item != fUserSelectedColorSpace) { 5991fc4cb1fSAxel Dörfler if (fUserSelectedColorSpace != NULL 6001fc4cb1fSAxel Dörfler && fUserSelectedColorSpace->IsEnabled()) { 6011fc4cb1fSAxel Dörfler fUserSelectedColorSpace->SetMarked(true); 6021fc4cb1fSAxel Dörfler item = fUserSelectedColorSpace; 6031fc4cb1fSAxel Dörfler changed = true; 6041fc4cb1fSAxel Dörfler } 6051fc4cb1fSAxel Dörfler } 6061fc4cb1fSAxel Dörfler if (item != NULL && !item->IsEnabled()) { 6071fc4cb1fSAxel Dörfler // find the next best item 6081fc4cb1fSAxel Dörfler int32 index = fColorsMenu->IndexOf(item); 6091fc4cb1fSAxel Dörfler bool found = false; 6101fc4cb1fSAxel Dörfler 6111fc4cb1fSAxel Dörfler for (int32 i = index + 1; i < fColorsMenu->CountItems(); i++) { 6121fc4cb1fSAxel Dörfler item = fColorsMenu->ItemAt(i); 6131fc4cb1fSAxel Dörfler if (item->IsEnabled()) { 6141fc4cb1fSAxel Dörfler found = true; 6151fc4cb1fSAxel Dörfler break; 6161fc4cb1fSAxel Dörfler } 6171fc4cb1fSAxel Dörfler } 6181fc4cb1fSAxel Dörfler if (!found) { 6191fc4cb1fSAxel Dörfler // search backwards as well 6201fc4cb1fSAxel Dörfler for (int32 i = index - 1; i >= 0; i--) { 6211fc4cb1fSAxel Dörfler item = fColorsMenu->ItemAt(i); 6221fc4cb1fSAxel Dörfler if (item->IsEnabled()) 6231fc4cb1fSAxel Dörfler break; 6241fc4cb1fSAxel Dörfler } 6251fc4cb1fSAxel Dörfler } 6261fc4cb1fSAxel Dörfler 6271fc4cb1fSAxel Dörfler item->SetMarked(true); 6281fc4cb1fSAxel Dörfler changed = true; 6291fc4cb1fSAxel Dörfler } 6301fc4cb1fSAxel Dörfler 6311fc4cb1fSAxel Dörfler if (changed) { 6321fc4cb1fSAxel Dörfler // Update selected space 6331fc4cb1fSAxel Dörfler 6341fc4cb1fSAxel Dörfler BMessage* message = item->Message(); 6351fc4cb1fSAxel Dörfler int32 space; 6361fc4cb1fSAxel Dörfler if (message->FindInt32("space", &space) == B_OK) { 6371fc4cb1fSAxel Dörfler fSelected.space = (color_space)space; 6381fc4cb1fSAxel Dörfler _UpdateColorLabel(); 6391fc4cb1fSAxel Dörfler } 6401fc4cb1fSAxel Dörfler } 641a10cf76eSAxel Dörfler } 642a10cf76eSAxel Dörfler 643a10cf76eSAxel Dörfler 6445de171daSAxel Dörfler /*! Enable/disable refresh options according to current mode. */ 645a10cf76eSAxel Dörfler void 6465de171daSAxel Dörfler ScreenWindow::_CheckRefreshMenu() 647a10cf76eSAxel Dörfler { 64829e8a73aSAxel Dörfler float min, max; 64929e8a73aSAxel Dörfler if (fScreenMode.GetRefreshLimits(fSelected, min, max) != B_OK || min == max) 65029e8a73aSAxel Dörfler return; 651a10cf76eSAxel Dörfler 65229e8a73aSAxel Dörfler for (int32 i = fRefreshMenu->CountItems(); i-- > 0;) { 65329e8a73aSAxel Dörfler BMenuItem* item = fRefreshMenu->ItemAt(i); 65429e8a73aSAxel Dörfler BMessage* message = item->Message(); 65529e8a73aSAxel Dörfler float refresh; 65629e8a73aSAxel Dörfler if (message != NULL && message->FindFloat("refresh", &refresh) == B_OK) 65729e8a73aSAxel Dörfler item->SetEnabled(refresh >= min && refresh <= max); 658a10cf76eSAxel Dörfler } 659a10cf76eSAxel Dörfler } 660a10cf76eSAxel Dörfler 661a10cf76eSAxel Dörfler 6625de171daSAxel Dörfler /*! Activate appropriate menu item according to selected refresh rate */ 663a10cf76eSAxel Dörfler void 6645de171daSAxel Dörfler ScreenWindow::_UpdateRefreshControl() 665a10cf76eSAxel Dörfler { 666a10cf76eSAxel Dörfler BString string; 667a10cf76eSAxel Dörfler refresh_rate_to_string(fSelected.refresh, string); 668a10cf76eSAxel Dörfler 669a10cf76eSAxel Dörfler BMenuItem* item = fRefreshMenu->FindItem(string.String()); 670a10cf76eSAxel Dörfler if (item) { 671a10cf76eSAxel Dörfler if (!item->IsMarked()) 672a10cf76eSAxel Dörfler item->SetMarked(true); 67329e8a73aSAxel Dörfler 67426747978SAdrien Destugues // "Other" items only contains a refresh rate when active 67526747978SAdrien Destugues fOtherRefresh->SetLabel(B_TRANSLATE("Other" B_UTF8_ELLIPSIS)); 676a10cf76eSAxel Dörfler return; 677a10cf76eSAxel Dörfler } 678a10cf76eSAxel Dörfler 679a10cf76eSAxel Dörfler // this is a non-standard refresh rate 680a10cf76eSAxel Dörfler 681a10cf76eSAxel Dörfler fOtherRefresh->Message()->ReplaceFloat("refresh", fSelected.refresh); 682a10cf76eSAxel Dörfler fOtherRefresh->SetMarked(true); 683a10cf76eSAxel Dörfler 684a10cf76eSAxel Dörfler fRefreshMenu->Superitem()->SetLabel(string.String()); 685a10cf76eSAxel Dörfler 686c9e8f97aSAdrien Destugues string.Append(B_TRANSLATE("/other" B_UTF8_ELLIPSIS)); 687a10cf76eSAxel Dörfler fOtherRefresh->SetLabel(string.String()); 688a10cf76eSAxel Dörfler } 689a10cf76eSAxel Dörfler 690a10cf76eSAxel Dörfler 691a10cf76eSAxel Dörfler void 6925de171daSAxel Dörfler ScreenWindow::_UpdateMonitorView() 693a10cf76eSAxel Dörfler { 694a10cf76eSAxel Dörfler BMessage updateMessage(UPDATE_DESKTOP_MSG); 695a10cf76eSAxel Dörfler updateMessage.AddInt32("width", fSelected.width); 696a10cf76eSAxel Dörfler updateMessage.AddInt32("height", fSelected.height); 697a10cf76eSAxel Dörfler 698a10cf76eSAxel Dörfler PostMessage(&updateMessage, fMonitorView); 699a10cf76eSAxel Dörfler } 700a10cf76eSAxel Dörfler 701a10cf76eSAxel Dörfler 702a10cf76eSAxel Dörfler void 7035de171daSAxel Dörfler ScreenWindow::_UpdateControls() 704a10cf76eSAxel Dörfler { 705b21d610eSAxel Dörfler _UpdateWorkspaceButtons(); 706b21d610eSAxel Dörfler 707a10cf76eSAxel Dörfler BMenuItem* item = fSwapDisplaysMenu->ItemAt((int32)fSelected.swap_displays); 708a10cf76eSAxel Dörfler if (item && !item->IsMarked()) 709a10cf76eSAxel Dörfler item->SetMarked(true); 710a10cf76eSAxel Dörfler 711a10cf76eSAxel Dörfler item = fUseLaptopPanelMenu->ItemAt((int32)fSelected.use_laptop_panel); 712a10cf76eSAxel Dörfler if (item && !item->IsMarked()) 713a10cf76eSAxel Dörfler item->SetMarked(true); 714a10cf76eSAxel Dörfler 715a10cf76eSAxel Dörfler for (int32 i = 0; i < fTVStandardMenu->CountItems(); i++) { 716a10cf76eSAxel Dörfler item = fTVStandardMenu->ItemAt(i); 717a10cf76eSAxel Dörfler 718a10cf76eSAxel Dörfler uint32 tvStandard; 719a10cf76eSAxel Dörfler item->Message()->FindInt32("tv_standard", (int32 *)&tvStandard); 720a10cf76eSAxel Dörfler if (tvStandard == fSelected.tv_standard) { 721a10cf76eSAxel Dörfler if (!item->IsMarked()) 722a10cf76eSAxel Dörfler item->SetMarked(true); 723a10cf76eSAxel Dörfler break; 724a10cf76eSAxel Dörfler } 725a10cf76eSAxel Dörfler } 726a10cf76eSAxel Dörfler 7275de171daSAxel Dörfler _CheckResolutionMenu(); 7285de171daSAxel Dörfler _CheckColorMenu(); 7295de171daSAxel Dörfler _CheckRefreshMenu(); 730a10cf76eSAxel Dörfler 731a10cf76eSAxel Dörfler BString string; 732a10cf76eSAxel Dörfler resolution_to_string(fSelected, string); 733a10cf76eSAxel Dörfler item = fResolutionMenu->FindItem(string.String()); 734a10cf76eSAxel Dörfler 735a10cf76eSAxel Dörfler if (item != NULL) { 736a10cf76eSAxel Dörfler if (!item->IsMarked()) 737a10cf76eSAxel Dörfler item->SetMarked(true); 738a10cf76eSAxel Dörfler } else { 739a10cf76eSAxel Dörfler // this is bad luck - if mode has been set via screen references, 740a10cf76eSAxel Dörfler // this case cannot occur; there are three possible solutions: 741a10cf76eSAxel Dörfler // 1. add a new resolution to list 742a10cf76eSAxel Dörfler // - we had to remove it as soon as a "valid" one is selected 743a10cf76eSAxel Dörfler // - we don't know which frequencies/bit depths are supported 744a10cf76eSAxel Dörfler // - as long as we haven't the GMT formula to create 745a10cf76eSAxel Dörfler // parameters for any resolution given, we cannot 746a10cf76eSAxel Dörfler // really set current mode - it's just not in the list 747a10cf76eSAxel Dörfler // 2. choose nearest resolution 748a10cf76eSAxel Dörfler // - probably a good idea, but implies coding and testing 749a10cf76eSAxel Dörfler // 3. choose lowest resolution 750a10cf76eSAxel Dörfler // - do you really think we are so lazy? yes, we are 751a10cf76eSAxel Dörfler item = fResolutionMenu->ItemAt(0); 752a10cf76eSAxel Dörfler if (item) 753a10cf76eSAxel Dörfler item->SetMarked(true); 754a10cf76eSAxel Dörfler 755a10cf76eSAxel Dörfler // okay - at least we set menu label to active resolution 756a10cf76eSAxel Dörfler fResolutionMenu->Superitem()->SetLabel(string.String()); 757a10cf76eSAxel Dörfler } 758a10cf76eSAxel Dörfler 759a10cf76eSAxel Dörfler // mark active combine mode 760a10cf76eSAxel Dörfler for (int32 i = 0; i < kCombineModeCount; i++) { 761a10cf76eSAxel Dörfler if (kCombineModes[i].mode == fSelected.combine) { 762a10cf76eSAxel Dörfler item = fCombineMenu->ItemAt(i); 763a10cf76eSAxel Dörfler if (item && !item->IsMarked()) 764a10cf76eSAxel Dörfler item->SetMarked(true); 765a10cf76eSAxel Dörfler break; 766a10cf76eSAxel Dörfler } 767a10cf76eSAxel Dörfler } 768a10cf76eSAxel Dörfler 769a10cf76eSAxel Dörfler item = fColorsMenu->ItemAt(0); 770a10cf76eSAxel Dörfler 7711fc4cb1fSAxel Dörfler for (int32 i = 0, index = 0; i < kColorSpaceCount; i++) { 7721fc4cb1fSAxel Dörfler if ((fSupportedColorSpaces & (1 << i)) == 0) 7731fc4cb1fSAxel Dörfler continue; 7741fc4cb1fSAxel Dörfler 7751fc4cb1fSAxel Dörfler if (kColorSpaces[i].space == fSelected.space) { 7761fc4cb1fSAxel Dörfler item = fColorsMenu->ItemAt(index); 777a10cf76eSAxel Dörfler break; 778a10cf76eSAxel Dörfler } 7791fc4cb1fSAxel Dörfler 7801fc4cb1fSAxel Dörfler index++; 781a10cf76eSAxel Dörfler } 782a10cf76eSAxel Dörfler 783a10cf76eSAxel Dörfler if (item && !item->IsMarked()) 784a10cf76eSAxel Dörfler item->SetMarked(true); 785a10cf76eSAxel Dörfler 7861fc4cb1fSAxel Dörfler _UpdateColorLabel(); 7875de171daSAxel Dörfler _UpdateMonitorView(); 7885de171daSAxel Dörfler _UpdateRefreshControl(); 789a10cf76eSAxel Dörfler 7905de171daSAxel Dörfler _CheckApplyEnabled(); 791a10cf76eSAxel Dörfler } 792a10cf76eSAxel Dörfler 793a10cf76eSAxel Dörfler 79412580984SAxel Dörfler /*! Reflect active mode in chosen settings */ 795a10cf76eSAxel Dörfler void 7965de171daSAxel Dörfler ScreenWindow::_UpdateActiveMode() 797a10cf76eSAxel Dörfler { 79812580984SAxel Dörfler // Usually, this function gets called after a mode 799a10cf76eSAxel Dörfler // has been set manually; still, as the graphics driver 800a10cf76eSAxel Dörfler // is free to fiddle with mode passed, we better ask 801a10cf76eSAxel Dörfler // what kind of mode we actually got 802a10cf76eSAxel Dörfler fScreenMode.Get(fActive); 803a10cf76eSAxel Dörfler fSelected = fActive; 804a10cf76eSAxel Dörfler 80512966d04SAxel Dörfler _UpdateMonitor(); 8065de171daSAxel Dörfler _UpdateControls(); 807a10cf76eSAxel Dörfler } 808a10cf76eSAxel Dörfler 809a10cf76eSAxel Dörfler 810a10cf76eSAxel Dörfler void 811b21d610eSAxel Dörfler ScreenWindow::_UpdateWorkspaceButtons() 812b21d610eSAxel Dörfler { 813b21d610eSAxel Dörfler uint32 columns; 814b21d610eSAxel Dörfler uint32 rows; 815b21d610eSAxel Dörfler BPrivate::get_workspaces_layout(&columns, &rows); 816b21d610eSAxel Dörfler 817b21d610eSAxel Dörfler char text[32]; 818b21d610eSAxel Dörfler snprintf(text, sizeof(text), "%ld", columns); 819b21d610eSAxel Dörfler fColumnsControl->SetText(text); 820b21d610eSAxel Dörfler 821b21d610eSAxel Dörfler snprintf(text, sizeof(text), "%ld", rows); 822b21d610eSAxel Dörfler fRowsControl->SetText(text); 823b21d610eSAxel Dörfler 824b21d610eSAxel Dörfler _GetColumnRowButton(true, false)->SetEnabled(columns != 1 && rows != 32); 825b21d610eSAxel Dörfler _GetColumnRowButton(true, true)->SetEnabled((columns + 1) * rows < 32); 826b21d610eSAxel Dörfler _GetColumnRowButton(false, false)->SetEnabled(rows != 1 && columns != 32); 827b21d610eSAxel Dörfler _GetColumnRowButton(false, true)->SetEnabled(columns * (rows + 1) < 32); 828b21d610eSAxel Dörfler } 829b21d610eSAxel Dörfler 830b21d610eSAxel Dörfler 831b21d610eSAxel Dörfler void 832a10cf76eSAxel Dörfler ScreenWindow::ScreenChanged(BRect frame, color_space mode) 833a10cf76eSAxel Dörfler { 834a10cf76eSAxel Dörfler // move window on screen, if necessary 835a10cf76eSAxel Dörfler if (frame.right <= Frame().right 836a10cf76eSAxel Dörfler && frame.bottom <= Frame().bottom) { 837a10cf76eSAxel Dörfler MoveTo((frame.Width() - Frame().Width()) / 2, 838a10cf76eSAxel Dörfler (frame.Height() - Frame().Height()) / 2); 839a10cf76eSAxel Dörfler } 840a10cf76eSAxel Dörfler } 841a10cf76eSAxel Dörfler 842a10cf76eSAxel Dörfler 843a10cf76eSAxel Dörfler void 844a10cf76eSAxel Dörfler ScreenWindow::WorkspaceActivated(int32 workspace, bool state) 845a10cf76eSAxel Dörfler { 846abc649b8SWaldemar Kornewald fScreenMode.GetOriginalMode(fOriginal, workspace); 8475de171daSAxel Dörfler _UpdateActiveMode(); 848a10cf76eSAxel Dörfler 8496edaa0f6SStefano Ceccherini BMessage message(UPDATE_DESKTOP_COLOR_MSG); 8506edaa0f6SStefano Ceccherini PostMessage(&message, fMonitorView); 851a10cf76eSAxel Dörfler } 852a10cf76eSAxel Dörfler 853a10cf76eSAxel Dörfler 854a10cf76eSAxel Dörfler void 855a10cf76eSAxel Dörfler ScreenWindow::MessageReceived(BMessage* message) 856a10cf76eSAxel Dörfler { 857a10cf76eSAxel Dörfler switch (message->what) { 858a10cf76eSAxel Dörfler case WORKSPACE_CHECK_MSG: 8595de171daSAxel Dörfler _CheckApplyEnabled(); 860a10cf76eSAxel Dörfler break; 861a10cf76eSAxel Dörfler 862b21d610eSAxel Dörfler case kMsgWorkspaceLayoutChanged: 863a10cf76eSAxel Dörfler { 864b21d610eSAxel Dörfler int32 deltaX = 0; 865b21d610eSAxel Dörfler int32 deltaY = 0; 866b21d610eSAxel Dörfler message->FindInt32("delta_x", &deltaX); 867b21d610eSAxel Dörfler message->FindInt32("delta_y", &deltaY); 868b21d610eSAxel Dörfler 869b21d610eSAxel Dörfler if (deltaX == 0 && deltaY == 0) 870b21d610eSAxel Dörfler break; 871b21d610eSAxel Dörfler 872b21d610eSAxel Dörfler uint32 newColumns; 873b21d610eSAxel Dörfler uint32 newRows; 874b21d610eSAxel Dörfler BPrivate::get_workspaces_layout(&newColumns, &newRows); 875b21d610eSAxel Dörfler 876b21d610eSAxel Dörfler newColumns += deltaX; 877b21d610eSAxel Dörfler newRows += deltaY; 878b21d610eSAxel Dörfler BPrivate::set_workspaces_layout(newColumns, newRows); 879b21d610eSAxel Dörfler 880b21d610eSAxel Dörfler _UpdateWorkspaceButtons(); 8815de171daSAxel Dörfler _CheckApplyEnabled(); 882b21d610eSAxel Dörfler break; 883abc649b8SWaldemar Kornewald } 884b21d610eSAxel Dörfler 885b21d610eSAxel Dörfler case kMsgWorkspaceColumnsChanged: 886b21d610eSAxel Dörfler { 887b21d610eSAxel Dörfler uint32 newColumns = strtoul(fColumnsControl->Text(), NULL, 10); 888b21d610eSAxel Dörfler 889b21d610eSAxel Dörfler uint32 rows; 890b21d610eSAxel Dörfler BPrivate::get_workspaces_layout(NULL, &rows); 891b21d610eSAxel Dörfler BPrivate::set_workspaces_layout(newColumns, rows); 892b21d610eSAxel Dörfler 893b21d610eSAxel Dörfler _UpdateWorkspaceButtons(); 894b21d610eSAxel Dörfler _CheckApplyEnabled(); 895b21d610eSAxel Dörfler break; 896b21d610eSAxel Dörfler } 897b21d610eSAxel Dörfler 898b21d610eSAxel Dörfler case kMsgWorkspaceRowsChanged: 899b21d610eSAxel Dörfler { 900b21d610eSAxel Dörfler uint32 newRows = strtoul(fRowsControl->Text(), NULL, 10); 901b21d610eSAxel Dörfler 902b21d610eSAxel Dörfler uint32 columns; 903b21d610eSAxel Dörfler BPrivate::get_workspaces_layout(&columns, NULL); 904b21d610eSAxel Dörfler BPrivate::set_workspaces_layout(columns, newRows); 905b21d610eSAxel Dörfler 906b21d610eSAxel Dörfler _UpdateWorkspaceButtons(); 907b21d610eSAxel Dörfler _CheckApplyEnabled(); 908a10cf76eSAxel Dörfler break; 909a10cf76eSAxel Dörfler } 910a10cf76eSAxel Dörfler 911a10cf76eSAxel Dörfler case POP_RESOLUTION_MSG: 912a10cf76eSAxel Dörfler { 913a10cf76eSAxel Dörfler message->FindInt32("width", &fSelected.width); 914a10cf76eSAxel Dörfler message->FindInt32("height", &fSelected.height); 915a10cf76eSAxel Dörfler 9165de171daSAxel Dörfler _CheckColorMenu(); 9175de171daSAxel Dörfler _CheckRefreshMenu(); 918a10cf76eSAxel Dörfler 9195de171daSAxel Dörfler _UpdateMonitorView(); 9205de171daSAxel Dörfler _UpdateRefreshControl(); 921a10cf76eSAxel Dörfler 9225de171daSAxel Dörfler _CheckApplyEnabled(); 923a10cf76eSAxel Dörfler break; 924a10cf76eSAxel Dörfler } 925a10cf76eSAxel Dörfler 926a10cf76eSAxel Dörfler case POP_COLORS_MSG: 927a10cf76eSAxel Dörfler { 9281fc4cb1fSAxel Dörfler int32 space; 9291fc4cb1fSAxel Dörfler if (message->FindInt32("space", &space) != B_OK) 9301fc4cb1fSAxel Dörfler break; 931a10cf76eSAxel Dörfler 9321fc4cb1fSAxel Dörfler int32 index; 9331fc4cb1fSAxel Dörfler if (message->FindInt32("index", &index) == B_OK 9341fc4cb1fSAxel Dörfler && fColorsMenu->ItemAt(index) != NULL) 9351fc4cb1fSAxel Dörfler fUserSelectedColorSpace = fColorsMenu->ItemAt(index); 9361fc4cb1fSAxel Dörfler 9371fc4cb1fSAxel Dörfler fSelected.space = (color_space)space; 9381fc4cb1fSAxel Dörfler _UpdateColorLabel(); 939a10cf76eSAxel Dörfler 9405de171daSAxel Dörfler _CheckApplyEnabled(); 941a10cf76eSAxel Dörfler break; 942a10cf76eSAxel Dörfler } 943a10cf76eSAxel Dörfler 944a10cf76eSAxel Dörfler case POP_REFRESH_MSG: 945a40498e2SWaldemar Kornewald { 946a10cf76eSAxel Dörfler message->FindFloat("refresh", &fSelected.refresh); 947c9e8f97aSAdrien Destugues fOtherRefresh->SetLabel(B_TRANSLATE("Other" B_UTF8_ELLIPSIS)); 9481fc4cb1fSAxel Dörfler // revert "Other…" label - it might have a refresh rate prefix 949a10cf76eSAxel Dörfler 9505de171daSAxel Dörfler _CheckApplyEnabled(); 951a10cf76eSAxel Dörfler break; 952a40498e2SWaldemar Kornewald } 953a10cf76eSAxel Dörfler 954a10cf76eSAxel Dörfler case POP_OTHER_REFRESH_MSG: 955a10cf76eSAxel Dörfler { 95629e8a73aSAxel Dörfler // make sure menu shows something useful 9575de171daSAxel Dörfler _UpdateRefreshControl(); 958a10cf76eSAxel Dörfler 95929e8a73aSAxel Dörfler float min = 0, max = 999; 96029e8a73aSAxel Dörfler fScreenMode.GetRefreshLimits(fSelected, min, max); 96129e8a73aSAxel Dörfler if (min < gMinRefresh) 96229e8a73aSAxel Dörfler min = gMinRefresh; 96329e8a73aSAxel Dörfler if (max > gMaxRefresh) 96429e8a73aSAxel Dörfler max = gMaxRefresh; 96529e8a73aSAxel Dörfler 96670a2b1b5SAxel Dörfler monitor_info info; 96770a2b1b5SAxel Dörfler if (fScreenMode.GetMonitorInfo(info) == B_OK) { 96870a2b1b5SAxel Dörfler min = max_c(info.min_vertical_frequency, min); 96970a2b1b5SAxel Dörfler max = min_c(info.max_vertical_frequency, max); 97070a2b1b5SAxel Dörfler } 97170a2b1b5SAxel Dörfler 972c5d10f7aSAxel Dörfler RefreshWindow *fRefreshWindow = new RefreshWindow( 97370a2b1b5SAxel Dörfler fRefreshField->ConvertToScreen(B_ORIGIN), fSelected.refresh, 97470a2b1b5SAxel Dörfler min, max); 975a10cf76eSAxel Dörfler fRefreshWindow->Show(); 976a10cf76eSAxel Dörfler break; 977a10cf76eSAxel Dörfler } 978a10cf76eSAxel Dörfler 979a10cf76eSAxel Dörfler case SET_CUSTOM_REFRESH_MSG: 980a10cf76eSAxel Dörfler { 981a10cf76eSAxel Dörfler // user pressed "done" in "Other…" refresh dialog; 982a10cf76eSAxel Dörfler // select the refresh rate chosen 983a10cf76eSAxel Dörfler message->FindFloat("refresh", &fSelected.refresh); 984a10cf76eSAxel Dörfler 9855de171daSAxel Dörfler _UpdateRefreshControl(); 9865de171daSAxel Dörfler _CheckApplyEnabled(); 987a10cf76eSAxel Dörfler break; 988a10cf76eSAxel Dörfler } 989a10cf76eSAxel Dörfler 990a10cf76eSAxel Dörfler case POP_COMBINE_DISPLAYS_MSG: 991a10cf76eSAxel Dörfler { 992a10cf76eSAxel Dörfler // new combine mode has bee chosen 993a10cf76eSAxel Dörfler int32 mode; 994a10cf76eSAxel Dörfler if (message->FindInt32("mode", &mode) == B_OK) 995a10cf76eSAxel Dörfler fSelected.combine = (combine_mode)mode; 996a10cf76eSAxel Dörfler 9975de171daSAxel Dörfler _CheckResolutionMenu(); 9985de171daSAxel Dörfler _CheckApplyEnabled(); 999a10cf76eSAxel Dörfler break; 1000a10cf76eSAxel Dörfler } 1001a10cf76eSAxel Dörfler 1002a10cf76eSAxel Dörfler case POP_SWAP_DISPLAYS_MSG: 1003a10cf76eSAxel Dörfler message->FindBool("swap", &fSelected.swap_displays); 10045de171daSAxel Dörfler _CheckApplyEnabled(); 1005a10cf76eSAxel Dörfler break; 1006a10cf76eSAxel Dörfler 1007a10cf76eSAxel Dörfler case POP_USE_LAPTOP_PANEL_MSG: 1008a10cf76eSAxel Dörfler message->FindBool("use", &fSelected.use_laptop_panel); 10095de171daSAxel Dörfler _CheckApplyEnabled(); 1010a10cf76eSAxel Dörfler break; 1011a10cf76eSAxel Dörfler 1012a10cf76eSAxel Dörfler case POP_TV_STANDARD_MSG: 1013a10cf76eSAxel Dörfler message->FindInt32("tv_standard", (int32 *)&fSelected.tv_standard); 10145de171daSAxel Dörfler _CheckApplyEnabled(); 1015a10cf76eSAxel Dörfler break; 1016a10cf76eSAxel Dörfler 1017df3f5bacSStephan Aßmus case BUTTON_LAUNCH_BACKGROUNDS_MSG: 10186f095d6aSRyan Leavengood if (be_roster->Launch(kBackgroundsSignature) == B_ALREADY_RUNNING) { 10196f095d6aSRyan Leavengood app_info info; 10206f095d6aSRyan Leavengood be_roster->GetAppInfo(kBackgroundsSignature, &info); 10216f095d6aSRyan Leavengood be_roster->ActivateApp(info.team); 10226f095d6aSRyan Leavengood } 1023df3f5bacSStephan Aßmus break; 1024df3f5bacSStephan Aßmus 1025a10cf76eSAxel Dörfler case BUTTON_DEFAULTS_MSG: 1026a10cf76eSAxel Dörfler { 10274be51fe3SWaldemar Kornewald // TODO: get preferred settings of screen 1028a10cf76eSAxel Dörfler fSelected.width = 640; 1029a10cf76eSAxel Dörfler fSelected.height = 480; 1030a10cf76eSAxel Dörfler fSelected.space = B_CMAP8; 1031a10cf76eSAxel Dörfler fSelected.refresh = 60.0; 1032a10cf76eSAxel Dörfler fSelected.combine = kCombineDisable; 1033a10cf76eSAxel Dörfler fSelected.swap_displays = false; 1034a10cf76eSAxel Dörfler fSelected.use_laptop_panel = false; 1035a10cf76eSAxel Dörfler fSelected.tv_standard = 0; 1036a10cf76eSAxel Dörfler 1037b21d610eSAxel Dörfler // TODO: workspace defaults 1038abc649b8SWaldemar Kornewald 10395de171daSAxel Dörfler _UpdateControls(); 1040a10cf76eSAxel Dörfler break; 1041a10cf76eSAxel Dörfler } 1042a10cf76eSAxel Dörfler 104310e9b12fSWaldemar Kornewald case BUTTON_UNDO_MSG: 104461c5c89bSAxel Dörfler fUndoScreenMode.Revert(); 10455de171daSAxel Dörfler _UpdateActiveMode(); 1046abc649b8SWaldemar Kornewald break; 1047abc649b8SWaldemar Kornewald 1048abc649b8SWaldemar Kornewald case BUTTON_REVERT_MSG: 1049abc649b8SWaldemar Kornewald { 1050abc649b8SWaldemar Kornewald fModified = false; 1051199893c3SAxel Dörfler fBootWorkspaceApplied = false; 1052abc649b8SWaldemar Kornewald 1053b21d610eSAxel Dörfler // ScreenMode::Revert() assumes that we first set the correct 1054b21d610eSAxel Dörfler // number of workspaces 1055b21d610eSAxel Dörfler 1056b21d610eSAxel Dörfler BPrivate::set_workspaces_layout(fOriginalWorkspacesColumns, 1057b21d610eSAxel Dörfler fOriginalWorkspacesRows); 1058b21d610eSAxel Dörfler _UpdateWorkspaceButtons(); 1059b21d610eSAxel Dörfler 1060a10cf76eSAxel Dörfler fScreenMode.Revert(); 10615de171daSAxel Dörfler _UpdateActiveMode(); 1062a10cf76eSAxel Dörfler break; 1063abc649b8SWaldemar Kornewald } 1064a10cf76eSAxel Dörfler 1065a10cf76eSAxel Dörfler case BUTTON_APPLY_MSG: 10665de171daSAxel Dörfler _Apply(); 1067a10cf76eSAxel Dörfler break; 1068a10cf76eSAxel Dörfler 1069abc649b8SWaldemar Kornewald case MAKE_INITIAL_MSG: 1070abc649b8SWaldemar Kornewald // user pressed "keep" in confirmation dialog 1071abc649b8SWaldemar Kornewald fModified = true; 10725de171daSAxel Dörfler _UpdateActiveMode(); 1073a10cf76eSAxel Dörfler break; 1074a10cf76eSAxel Dörfler 1075a10cf76eSAxel Dörfler default: 1076a10cf76eSAxel Dörfler BWindow::MessageReceived(message); 1077a10cf76eSAxel Dörfler break; 1078a10cf76eSAxel Dörfler } 1079a10cf76eSAxel Dörfler } 1080a10cf76eSAxel Dörfler 1081a10cf76eSAxel Dörfler 108212580984SAxel Dörfler status_t 108312580984SAxel Dörfler ScreenWindow::_WriteVesaModeFile(const screen_mode& mode) const 108412580984SAxel Dörfler { 108512580984SAxel Dörfler BPath path; 108612580984SAxel Dörfler status_t status = find_directory(B_USER_SETTINGS_DIRECTORY, &path, true); 108712580984SAxel Dörfler if (status < B_OK) 108812580984SAxel Dörfler return status; 108912580984SAxel Dörfler 109012580984SAxel Dörfler path.Append("kernel/drivers"); 109112580984SAxel Dörfler status = create_directory(path.Path(), 0755); 109212580984SAxel Dörfler if (status < B_OK) 109312580984SAxel Dörfler return status; 109412580984SAxel Dörfler 109512580984SAxel Dörfler path.Append("vesa"); 109612580984SAxel Dörfler BFile file; 109712580984SAxel Dörfler status = file.SetTo(path.Path(), B_CREATE_FILE | B_WRITE_ONLY | B_ERASE_FILE); 109812580984SAxel Dörfler if (status < B_OK) 109912580984SAxel Dörfler return status; 110012580984SAxel Dörfler 110112580984SAxel Dörfler char buffer[256]; 110212580984SAxel Dörfler snprintf(buffer, sizeof(buffer), "mode %ld %ld %ld\n", 110312580984SAxel Dörfler mode.width, mode.height, mode.BitsPerPixel()); 110412580984SAxel Dörfler 110512580984SAxel Dörfler ssize_t bytesWritten = file.Write(buffer, strlen(buffer)); 110612580984SAxel Dörfler if (bytesWritten < B_OK) 110712580984SAxel Dörfler return bytesWritten; 110812580984SAxel Dörfler 110912580984SAxel Dörfler return B_OK; 111012580984SAxel Dörfler } 111112580984SAxel Dörfler 111212580984SAxel Dörfler 1113b21d610eSAxel Dörfler BButton* 1114b21d610eSAxel Dörfler ScreenWindow::_CreateColumnRowButton(bool columns, bool plus) 1115b21d610eSAxel Dörfler { 1116b21d610eSAxel Dörfler BMessage* message = new BMessage(kMsgWorkspaceLayoutChanged); 1117b21d610eSAxel Dörfler message->AddInt32("delta_x", columns ? (plus ? 1 : -1) : 0); 1118b21d610eSAxel Dörfler message->AddInt32("delta_y", !columns ? (plus ? 1 : -1) : 0); 1119b21d610eSAxel Dörfler 1120b21d610eSAxel Dörfler BButton* button = new BButton(plus ? "+" : "-", message); 1121b21d610eSAxel Dörfler button->SetFontSize(be_plain_font->Size() * 0.9); 1122b21d610eSAxel Dörfler 1123b21d610eSAxel Dörfler BSize size = button->MinSize(); 1124b21d610eSAxel Dörfler size.width = button->StringWidth("+") + 16; 1125b21d610eSAxel Dörfler button->SetExplicitMinSize(size); 1126b21d610eSAxel Dörfler button->SetExplicitMaxSize(size); 1127b21d610eSAxel Dörfler 1128b21d610eSAxel Dörfler fWorkspacesButtons[(columns ? 0 : 2) + (plus ? 1 : 0)] = button; 1129b21d610eSAxel Dörfler return button; 1130b21d610eSAxel Dörfler } 1131b21d610eSAxel Dörfler 1132b21d610eSAxel Dörfler 1133b21d610eSAxel Dörfler BButton* 1134b21d610eSAxel Dörfler ScreenWindow::_GetColumnRowButton(bool columns, bool plus) 1135b21d610eSAxel Dörfler { 1136b21d610eSAxel Dörfler return fWorkspacesButtons[(columns ? 0 : 2) + (plus ? 1 : 0)]; 1137b21d610eSAxel Dörfler } 1138b21d610eSAxel Dörfler 1139b21d610eSAxel Dörfler 1140a10cf76eSAxel Dörfler void 11411fc4cb1fSAxel Dörfler ScreenWindow::_BuildSupportedColorSpaces() 11421fc4cb1fSAxel Dörfler { 11431fc4cb1fSAxel Dörfler fSupportedColorSpaces = 0; 11441fc4cb1fSAxel Dörfler 11451fc4cb1fSAxel Dörfler for (int32 i = 0; i < kColorSpaceCount; i++) { 11461fc4cb1fSAxel Dörfler for (int32 j = 0; j < fScreenMode.CountModes(); j++) { 11471fc4cb1fSAxel Dörfler if (fScreenMode.ModeAt(j).space == kColorSpaces[i].space) { 11481fc4cb1fSAxel Dörfler fSupportedColorSpaces |= 1 << i; 11491fc4cb1fSAxel Dörfler break; 11501fc4cb1fSAxel Dörfler } 11511fc4cb1fSAxel Dörfler } 11521fc4cb1fSAxel Dörfler } 11531fc4cb1fSAxel Dörfler } 11541fc4cb1fSAxel Dörfler 11551fc4cb1fSAxel Dörfler 11561fc4cb1fSAxel Dörfler void 11575de171daSAxel Dörfler ScreenWindow::_CheckApplyEnabled() 1158a10cf76eSAxel Dörfler { 115927c43a2dSRene Gollent fApplyButton->SetEnabled(fSelected != fActive 116027c43a2dSRene Gollent || fAllWorkspacesItem->IsMarked()); 1161b21d610eSAxel Dörfler 1162b21d610eSAxel Dörfler uint32 columns; 1163b21d610eSAxel Dörfler uint32 rows; 1164b21d610eSAxel Dörfler BPrivate::get_workspaces_layout(&columns, &rows); 1165b21d610eSAxel Dörfler 1166b21d610eSAxel Dörfler fRevertButton->SetEnabled(columns != fOriginalWorkspacesColumns 1167b21d610eSAxel Dörfler || rows != fOriginalWorkspacesRows 11685de171daSAxel Dörfler || fSelected != fOriginal); 1169a10cf76eSAxel Dörfler } 1170a10cf76eSAxel Dörfler 1171a10cf76eSAxel Dörfler 1172a10cf76eSAxel Dörfler void 11735de171daSAxel Dörfler ScreenWindow::_UpdateOriginal() 1174abc649b8SWaldemar Kornewald { 1175b21d610eSAxel Dörfler BPrivate::get_workspaces_layout(&fOriginalWorkspacesColumns, 1176b21d610eSAxel Dörfler &fOriginalWorkspacesRows); 1177b21d610eSAxel Dörfler 1178abc649b8SWaldemar Kornewald fScreenMode.Get(fOriginal); 1179abc649b8SWaldemar Kornewald fScreenMode.UpdateOriginalModes(); 1180abc649b8SWaldemar Kornewald } 1181abc649b8SWaldemar Kornewald 1182abc649b8SWaldemar Kornewald 1183abc649b8SWaldemar Kornewald void 118412966d04SAxel Dörfler ScreenWindow::_UpdateMonitor() 118512966d04SAxel Dörfler { 118612966d04SAxel Dörfler monitor_info info; 118712966d04SAxel Dörfler float diagonalInches; 118812966d04SAxel Dörfler status_t status = fScreenMode.GetMonitorInfo(info, &diagonalInches); 118955030977SAxel Dörfler if (status == B_OK) { 11901a8af605SAxel Dörfler char text[512]; 119166ab1666SAxel Dörfler snprintf(text, sizeof(text), "%s%s%s %g\"", info.vendor, 119266ab1666SAxel Dörfler info.name[0] ? " " : "", info.name, diagonalInches); 119312966d04SAxel Dörfler 119412966d04SAxel Dörfler fMonitorInfo->SetText(text); 119512966d04SAxel Dörfler 119612966d04SAxel Dörfler if (fMonitorInfo->IsHidden()) 119712966d04SAxel Dörfler fMonitorInfo->Show(); 119855030977SAxel Dörfler } else { 119955030977SAxel Dörfler if (!fMonitorInfo->IsHidden()) 120055030977SAxel Dörfler fMonitorInfo->Hide(); 120155030977SAxel Dörfler } 1202af8f9c31SAxel Dörfler 120355030977SAxel Dörfler char text[512]; 12041a8af605SAxel Dörfler size_t length = 0; 12051a8af605SAxel Dörfler text[0] = 0; 12061a8af605SAxel Dörfler 120755030977SAxel Dörfler if (status == B_OK) { 1208af8f9c31SAxel Dörfler if (info.min_horizontal_frequency != 0 1209af8f9c31SAxel Dörfler && info.min_vertical_frequency != 0 1210af8f9c31SAxel Dörfler && info.max_pixel_clock != 0) { 12111a8af605SAxel Dörfler length = snprintf(text, sizeof(text), 1212c9e8f97aSAdrien Destugues B_TRANSLATE("Horizonal frequency:\t%lu - %lu kHz\n" 12139c1a9b92SAdrien Destugues "Vertical frequency:\t%lu - %lu Hz\n\n" 1214c9e8f97aSAdrien Destugues "Maximum pixel clock:\t%g MHz"), 12151a8af605SAxel Dörfler info.min_horizontal_frequency, info.max_horizontal_frequency, 12161a8af605SAxel Dörfler info.min_vertical_frequency, info.max_vertical_frequency, 12171a8af605SAxel Dörfler info.max_pixel_clock / 1000.0); 1218af8f9c31SAxel Dörfler } 12191a8af605SAxel Dörfler if (info.serial_number[0] && length < sizeof(text)) { 12201a8af605SAxel Dörfler length += snprintf(text + length, sizeof(text) - length, 1221c9e8f97aSAdrien Destugues B_TRANSLATE("%sSerial no.: %s"), length ? "\n\n" : "", 12221a8af605SAxel Dörfler info.serial_number); 12231a8af605SAxel Dörfler if (info.produced.week != 0 && info.produced.year != 0 12241a8af605SAxel Dörfler && length < sizeof(text)) { 12251a8af605SAxel Dörfler length += snprintf(text + length, sizeof(text) - length, 12261a8af605SAxel Dörfler " (%u/%u)", info.produced.week, info.produced.year); 12271a8af605SAxel Dörfler } 12281a8af605SAxel Dörfler } 122955030977SAxel Dörfler } 123061c5c89bSAxel Dörfler 123161c5c89bSAxel Dörfler // Add info about the graphics device 123261c5c89bSAxel Dörfler 123361c5c89bSAxel Dörfler accelerant_device_info deviceInfo; 123461c5c89bSAxel Dörfler if (fScreenMode.GetDeviceInfo(deviceInfo) == B_OK 123561c5c89bSAxel Dörfler && length < sizeof(text)) { 123661c5c89bSAxel Dörfler if (deviceInfo.name[0] && deviceInfo.chipset[0]) { 123761c5c89bSAxel Dörfler length += snprintf(text + length, sizeof(text) - length, 123861c5c89bSAxel Dörfler "%s%s (%s)", length != 0 ? "\n\n" : "", deviceInfo.name, 123961c5c89bSAxel Dörfler deviceInfo.chipset); 124061c5c89bSAxel Dörfler } else if (deviceInfo.name[0] || deviceInfo.chipset[0]) { 124161c5c89bSAxel Dörfler length += snprintf(text + length, sizeof(text) - length, 124261c5c89bSAxel Dörfler "%s%s", length != 0 ? "\n\n" : "", deviceInfo.name[0] 124361c5c89bSAxel Dörfler ? deviceInfo.name : deviceInfo.chipset); 124461c5c89bSAxel Dörfler } 124561c5c89bSAxel Dörfler } 124661c5c89bSAxel Dörfler 12471a8af605SAxel Dörfler if (text[0]) 12481a8af605SAxel Dörfler fMonitorView->SetToolTip(text); 124912966d04SAxel Dörfler } 125012966d04SAxel Dörfler 125112966d04SAxel Dörfler 125212966d04SAxel Dörfler void 12531fc4cb1fSAxel Dörfler ScreenWindow::_UpdateColorLabel() 12541fc4cb1fSAxel Dörfler { 12551fc4cb1fSAxel Dörfler BString string; 1256551c9f15SSiarzhuk Zharski string << fSelected.BitsPerPixel() << " " << B_TRANSLATE("bits/pixel"); 12571fc4cb1fSAxel Dörfler fColorsMenu->Superitem()->SetLabel(string.String()); 12581fc4cb1fSAxel Dörfler } 12591fc4cb1fSAxel Dörfler 12601fc4cb1fSAxel Dörfler 12611fc4cb1fSAxel Dörfler void 12625de171daSAxel Dörfler ScreenWindow::_Apply() 1263a10cf76eSAxel Dörfler { 1264abc649b8SWaldemar Kornewald // make checkpoint, so we can undo these changes 126561c5c89bSAxel Dörfler fUndoScreenMode.UpdateOriginalModes(); 126661c5c89bSAxel Dörfler 126707184a9eSAxel Dörfler status_t status = fScreenMode.Set(fSelected); 126807184a9eSAxel Dörfler if (status == B_OK) { 1269abc649b8SWaldemar Kornewald // use the mode that has eventually been set and 1270abc649b8SWaldemar Kornewald // thus we know to be working; it can differ from 1271abc649b8SWaldemar Kornewald // the mode selected by user due to hardware limitation 1272abc649b8SWaldemar Kornewald display_mode newMode; 1273abc649b8SWaldemar Kornewald BScreen screen(this); 1274abc649b8SWaldemar Kornewald screen.GetMode(&newMode); 1275abc649b8SWaldemar Kornewald 1276abc649b8SWaldemar Kornewald if (fAllWorkspacesItem->IsMarked()) { 1277abc649b8SWaldemar Kornewald int32 originatingWorkspace = current_workspace(); 1278abc649b8SWaldemar Kornewald for (int32 i = 0; i < count_workspaces(); i++) { 1279abc649b8SWaldemar Kornewald if (i != originatingWorkspace) 1280abc649b8SWaldemar Kornewald screen.SetMode(i, &newMode, true); 1281abc649b8SWaldemar Kornewald } 1282199893c3SAxel Dörfler fBootWorkspaceApplied = true; 1283199893c3SAxel Dörfler } else { 1284199893c3SAxel Dörfler if (current_workspace() == 0) 1285199893c3SAxel Dörfler fBootWorkspaceApplied = true; 1286abc649b8SWaldemar Kornewald } 1287abc649b8SWaldemar Kornewald 1288a10cf76eSAxel Dörfler fActive = fSelected; 1289a10cf76eSAxel Dörfler 1290abc649b8SWaldemar Kornewald // TODO: only show alert when this is an unknown mode 1291a10cf76eSAxel Dörfler BWindow* window = new AlertWindow(this); 1292a10cf76eSAxel Dörfler window->Show(); 129307184a9eSAxel Dörfler } else { 129407184a9eSAxel Dörfler char message[256]; 129507184a9eSAxel Dörfler snprintf(message, sizeof(message), 1296c9e8f97aSAdrien Destugues B_TRANSLATE("The screen mode could not be set:\n\t%s\n"), 1297c9e8f97aSAdrien Destugues screen_errors(status)); 1298551c9f15SSiarzhuk Zharski BAlert* alert = new BAlert(B_TRANSLATE("Warning"), message, 1299c9e8f97aSAdrien Destugues B_TRANSLATE("OK"), NULL, NULL, 130007184a9eSAxel Dörfler B_WIDTH_AS_USUAL, B_WARNING_ALERT); 130107184a9eSAxel Dörfler alert->Go(); 1302a10cf76eSAxel Dörfler } 130307184a9eSAxel Dörfler } 130407184a9eSAxel Dörfler 1305