1*a10cf76eSAxel Dörfler /* 2*a10cf76eSAxel Dörfler * Copyright 2001-2005, Haiku. 3*a10cf76eSAxel Dörfler * Distributed under the terms of the MIT License. 4*a10cf76eSAxel Dörfler * 5*a10cf76eSAxel Dörfler * Authors: 6*a10cf76eSAxel Dörfler * Rafael Romo 7*a10cf76eSAxel Dörfler * Stefano Ceccherini (burton666@libero.it) 8*a10cf76eSAxel Dörfler * Andrew Bachmann 9*a10cf76eSAxel Dörfler * Thomas Kurschel 10*a10cf76eSAxel Dörfler * Axel Dörfler, axeld@pinc-software.de 11*a10cf76eSAxel Dörfler */ 12*a10cf76eSAxel Dörfler 13*a10cf76eSAxel Dörfler 14*a10cf76eSAxel Dörfler #include <Alert.h> 15*a10cf76eSAxel Dörfler #include <Application.h> 16*a10cf76eSAxel Dörfler #include <Box.h> 17*a10cf76eSAxel Dörfler #include <Button.h> 18*a10cf76eSAxel Dörfler #include <InterfaceDefs.h> 19*a10cf76eSAxel Dörfler #include <MenuItem.h> 20*a10cf76eSAxel Dörfler #include <MenuField.h> 21*a10cf76eSAxel Dörfler #include <Messenger.h> 22*a10cf76eSAxel Dörfler #include <PopUpMenu.h> 23*a10cf76eSAxel Dörfler #include <Screen.h> 24*a10cf76eSAxel Dörfler #include <String.h> 25*a10cf76eSAxel Dörfler #include <Window.h> 26*a10cf76eSAxel Dörfler 27*a10cf76eSAxel Dörfler #include <cstdio> 28*a10cf76eSAxel Dörfler #include <cstdlib> 29*a10cf76eSAxel Dörfler #include <cstring> 30*a10cf76eSAxel Dörfler 31*a10cf76eSAxel Dörfler #include "AlertWindow.h" 32*a10cf76eSAxel Dörfler #include "Constants.h" 33*a10cf76eSAxel Dörfler #include "RefreshWindow.h" 34*a10cf76eSAxel Dörfler #include "MonitorView.h" 35*a10cf76eSAxel Dörfler #include "ScreenSettings.h" 36*a10cf76eSAxel Dörfler #include "ScreenWindow.h" 37*a10cf76eSAxel Dörfler #include "Utility.h" 38*a10cf76eSAxel Dörfler 39*a10cf76eSAxel Dörfler /* Note, this headers defines a *private* interface to the Radeon accelerant. 40*a10cf76eSAxel Dörfler * It's a solution that works with the current BeOS interface that Haiku 41*a10cf76eSAxel Dörfler * adopted. 42*a10cf76eSAxel Dörfler * However, it's not a nice and clean solution. Don't use this header in any 43*a10cf76eSAxel Dörfler * application if you can avoid it. No other driver is using this, or should 44*a10cf76eSAxel Dörfler * be using this. 45*a10cf76eSAxel Dörfler * It will be replaced as soon as we introduce an updated accelerant interface 46*a10cf76eSAxel Dörfler * which may even happen before R1 hits the streets. 47*a10cf76eSAxel Dörfler */ 48*a10cf76eSAxel Dörfler 49*a10cf76eSAxel Dörfler #include "multimon.h" // the usual: DANGER WILL, ROBINSON! 50*a10cf76eSAxel Dörfler 51*a10cf76eSAxel Dörfler 52*a10cf76eSAxel Dörfler #define USE_FIXED_REFRESH 53*a10cf76eSAxel Dörfler // define to use fixed standard refresh rates 54*a10cf76eSAxel Dörfler // undefine to get standard refresh rates from driver 55*a10cf76eSAxel Dörfler 56*a10cf76eSAxel Dörfler 57*a10cf76eSAxel Dörfler // list of officially supported colour spaces 58*a10cf76eSAxel Dörfler static const struct { 59*a10cf76eSAxel Dörfler color_space space; 60*a10cf76eSAxel Dörfler int32 bits_per_pixel; 61*a10cf76eSAxel Dörfler const char* label; 62*a10cf76eSAxel Dörfler } kColorSpaces[] = { 63*a10cf76eSAxel Dörfler { B_CMAP8, 8, "8 Bits/Pixel, 256 Colors" }, 64*a10cf76eSAxel Dörfler { B_RGB15, 15, "15 Bits/Pixel, 32768 Colors" }, 65*a10cf76eSAxel Dörfler { B_RGB16, 16, "16 Bits/Pixel, 65536 Colors" }, 66*a10cf76eSAxel Dörfler { B_RGB32, 32, "32 Bits/Pixel, 16 Million Colors" } 67*a10cf76eSAxel Dörfler }; 68*a10cf76eSAxel Dörfler static const int32 kColorSpaceCount = sizeof(kColorSpaces) / sizeof(kColorSpaces[0]); 69*a10cf76eSAxel Dörfler 70*a10cf76eSAxel Dörfler // list of standard refresh rates 71*a10cf76eSAxel Dörfler static const int32 kRefreshRates[] = {56, 60, 70, 72, 75}; 72*a10cf76eSAxel Dörfler static const int32 kRefreshRateCount = sizeof(kRefreshRates) / sizeof(kRefreshRates[0]); 73*a10cf76eSAxel Dörfler 74*a10cf76eSAxel Dörfler 75*a10cf76eSAxel Dörfler // list of combine modes 76*a10cf76eSAxel Dörfler static const struct { 77*a10cf76eSAxel Dörfler combine_mode mode; 78*a10cf76eSAxel Dörfler const char *name; 79*a10cf76eSAxel Dörfler } kCombineModes[] = { 80*a10cf76eSAxel Dörfler { kCombineDisable, "disable" }, 81*a10cf76eSAxel Dörfler { kCombineHorizontally, "horizontally" }, 82*a10cf76eSAxel Dörfler { kCombineVertically, "vertically" } 83*a10cf76eSAxel Dörfler }; 84*a10cf76eSAxel Dörfler static const int32 kCombineModeCount = sizeof(kCombineModes) / sizeof(kCombineModes[0]); 85*a10cf76eSAxel Dörfler 86*a10cf76eSAxel Dörfler 87*a10cf76eSAxel Dörfler static BString 88*a10cf76eSAxel Dörfler tv_standard_to_string(uint32 mode) 89*a10cf76eSAxel Dörfler { 90*a10cf76eSAxel Dörfler switch (mode) { 91*a10cf76eSAxel Dörfler case 0: return "disabled"; 92*a10cf76eSAxel Dörfler case 1: return "NTSC"; 93*a10cf76eSAxel Dörfler case 2: return "NTSC Japan"; 94*a10cf76eSAxel Dörfler case 3: return "PAL BDGHI"; 95*a10cf76eSAxel Dörfler case 4: return "PAL M"; 96*a10cf76eSAxel Dörfler case 5: return "PAL N"; 97*a10cf76eSAxel Dörfler case 6: return "SECAM"; 98*a10cf76eSAxel Dörfler case 101: return "NTSC 443"; 99*a10cf76eSAxel Dörfler case 102: return "PAL 60"; 100*a10cf76eSAxel Dörfler case 103: return "PAL NC"; 101*a10cf76eSAxel Dörfler default: 102*a10cf76eSAxel Dörfler { 103*a10cf76eSAxel Dörfler BString name; 104*a10cf76eSAxel Dörfler name << "??? (" << mode << ")"; 105*a10cf76eSAxel Dörfler 106*a10cf76eSAxel Dörfler return name; 107*a10cf76eSAxel Dörfler } 108*a10cf76eSAxel Dörfler } 109*a10cf76eSAxel Dörfler } 110*a10cf76eSAxel Dörfler 111*a10cf76eSAxel Dörfler 112*a10cf76eSAxel Dörfler static void 113*a10cf76eSAxel Dörfler resolution_to_string(screen_mode& mode, BString &string) 114*a10cf76eSAxel Dörfler { 115*a10cf76eSAxel Dörfler string << mode.width << " x " << mode.height; 116*a10cf76eSAxel Dörfler } 117*a10cf76eSAxel Dörfler 118*a10cf76eSAxel Dörfler 119*a10cf76eSAxel Dörfler static void 120*a10cf76eSAxel Dörfler refresh_rate_to_string(float refresh, BString &string, 121*a10cf76eSAxel Dörfler bool appendUnit = true, bool alwaysWithFraction = false) 122*a10cf76eSAxel Dörfler { 123*a10cf76eSAxel Dörfler snprintf(string.LockBuffer(32), 32, "%.*g", refresh >= 100.0 ? 4 : 3, refresh); 124*a10cf76eSAxel Dörfler string.UnlockBuffer(); 125*a10cf76eSAxel Dörfler 126*a10cf76eSAxel Dörfler if (appendUnit) 127*a10cf76eSAxel Dörfler string << " Hz"; 128*a10cf76eSAxel Dörfler } 129*a10cf76eSAxel Dörfler 130*a10cf76eSAxel Dörfler 131*a10cf76eSAxel Dörfler // #pragma mark - 132*a10cf76eSAxel Dörfler 133*a10cf76eSAxel Dörfler 134*a10cf76eSAxel Dörfler ScreenWindow::ScreenWindow(ScreenSettings *Settings) 135*a10cf76eSAxel Dörfler : BWindow(Settings->WindowFrame(), "Screen", B_TITLED_WINDOW, 136*a10cf76eSAxel Dörfler B_NOT_RESIZABLE | B_NOT_ZOOMABLE, B_ALL_WORKSPACES), 137*a10cf76eSAxel Dörfler fScreenMode(this), 138*a10cf76eSAxel Dörfler fChangingAllWorkspaces(false) 139*a10cf76eSAxel Dörfler { 140*a10cf76eSAxel Dörfler BScreen screen(this); 141*a10cf76eSAxel Dörfler BRect frame(Bounds()); 142*a10cf76eSAxel Dörfler 143*a10cf76eSAxel Dörfler fScreenMode.Get(fOriginal); 144*a10cf76eSAxel Dörfler fActive = fSelected = fOriginal; 145*a10cf76eSAxel Dörfler 146*a10cf76eSAxel Dörfler BView *view = new BView(frame, "ScreenView", B_FOLLOW_ALL, B_WILL_DRAW); 147*a10cf76eSAxel Dörfler view->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 148*a10cf76eSAxel Dörfler AddChild(view); 149*a10cf76eSAxel Dörfler 150*a10cf76eSAxel Dörfler fSettings = Settings; 151*a10cf76eSAxel Dörfler 152*a10cf76eSAxel Dörfler // box on the left with workspace count and monitor view 153*a10cf76eSAxel Dörfler 154*a10cf76eSAxel Dörfler BRect screenBoxRect(11.0, 18.0, 153.0, 155.0); 155*a10cf76eSAxel Dörfler BBox *screenBox = new BBox(screenBoxRect, "left box"); 156*a10cf76eSAxel Dörfler 157*a10cf76eSAxel Dörfler fMonitorView = new MonitorView(BRect(20.0, 16.0, 122.0, 93.0), "monitor", 158*a10cf76eSAxel Dörfler screen.Frame().Width() + 1, screen.Frame().Height() + 1); 159*a10cf76eSAxel Dörfler screenBox->AddChild(fMonitorView); 160*a10cf76eSAxel Dörfler 161*a10cf76eSAxel Dörfler BPopUpMenu *popUpMenu = new BPopUpMenu("", true, true); 162*a10cf76eSAxel Dörfler BMenuField *menuField = new BMenuField(BRect(7.0, 107.0, 135.0, 127.0), 163*a10cf76eSAxel Dörfler "WorkspaceCountMenu", "Workspace count:", popUpMenu, true); 164*a10cf76eSAxel Dörfler screenBox->AddChild(menuField); 165*a10cf76eSAxel Dörfler 166*a10cf76eSAxel Dörfler for (int32 count = 1; count <= 32; count++) { 167*a10cf76eSAxel Dörfler BString workspaceCount; 168*a10cf76eSAxel Dörfler workspaceCount << count; 169*a10cf76eSAxel Dörfler 170*a10cf76eSAxel Dörfler BMessage *message = new BMessage(POP_WORKSPACE_CHANGED_MSG); 171*a10cf76eSAxel Dörfler message->AddInt32("workspace count", count); 172*a10cf76eSAxel Dörfler 173*a10cf76eSAxel Dörfler popUpMenu->AddItem(new BMenuItem(workspaceCount.String(), 174*a10cf76eSAxel Dörfler message)); 175*a10cf76eSAxel Dörfler } 176*a10cf76eSAxel Dörfler 177*a10cf76eSAxel Dörfler BMenuItem *item = popUpMenu->ItemAt(count_workspaces() - 1); 178*a10cf76eSAxel Dörfler if (item != NULL) 179*a10cf76eSAxel Dörfler item->SetMarked(true); 180*a10cf76eSAxel Dörfler 181*a10cf76eSAxel Dörfler menuField->SetDivider(91.0); 182*a10cf76eSAxel Dörfler view->AddChild(screenBox); 183*a10cf76eSAxel Dörfler 184*a10cf76eSAxel Dörfler // box on the right with screen resolution, etc. 185*a10cf76eSAxel Dörfler 186*a10cf76eSAxel Dörfler popUpMenu = new BPopUpMenu("Current Workspace", true, true); 187*a10cf76eSAxel Dörfler fAllWorkspacesItem = new BMenuItem("All Workspaces", new BMessage(WORKSPACE_CHECK_MSG)); 188*a10cf76eSAxel Dörfler popUpMenu->AddItem(fAllWorkspacesItem); 189*a10cf76eSAxel Dörfler item = new BMenuItem("Current Workspace", new BMessage(WORKSPACE_CHECK_MSG)); 190*a10cf76eSAxel Dörfler item->SetMarked(true); 191*a10cf76eSAxel Dörfler popUpMenu->AddItem(item); 192*a10cf76eSAxel Dörfler 193*a10cf76eSAxel Dörfler BRect rect(0.0, 0.0, 132.0, 18.0); 194*a10cf76eSAxel Dörfler menuField = new BMenuField(rect, "WorkspaceMenu", NULL, popUpMenu, true); 195*a10cf76eSAxel Dörfler 196*a10cf76eSAxel Dörfler rect.Set(164.0, 7.0, 345.0, 155.0); 197*a10cf76eSAxel Dörfler BBox* controlsBox = new BBox(rect); 198*a10cf76eSAxel Dörfler controlsBox->SetLabel(menuField); 199*a10cf76eSAxel Dörfler 200*a10cf76eSAxel Dörfler rect.Set(88.0, 114.0, 200.0, 150.0); 201*a10cf76eSAxel Dörfler fApplyButton = new BButton(rect, "ApplyButton", "Apply", 202*a10cf76eSAxel Dörfler new BMessage(BUTTON_APPLY_MSG)); 203*a10cf76eSAxel Dörfler fApplyButton->ResizeToPreferred(); 204*a10cf76eSAxel Dörfler fApplyButton->SetEnabled(false); 205*a10cf76eSAxel Dörfler 206*a10cf76eSAxel Dörfler controlsBox->AddChild(fApplyButton); 207*a10cf76eSAxel Dörfler 208*a10cf76eSAxel Dörfler fResolutionMenu = new BPopUpMenu("resolution", true, true); 209*a10cf76eSAxel Dörfler 210*a10cf76eSAxel Dörfler uint16 previousWidth = 0, previousHeight = 0; 211*a10cf76eSAxel Dörfler for (int32 i = 0; i < fScreenMode.CountModes(); i++) { 212*a10cf76eSAxel Dörfler screen_mode mode = fScreenMode.ModeAt(i); 213*a10cf76eSAxel Dörfler 214*a10cf76eSAxel Dörfler if (mode.width == previousWidth && mode.height == previousHeight) 215*a10cf76eSAxel Dörfler continue; 216*a10cf76eSAxel Dörfler 217*a10cf76eSAxel Dörfler previousWidth = mode.width; 218*a10cf76eSAxel Dörfler previousHeight = mode.height; 219*a10cf76eSAxel Dörfler 220*a10cf76eSAxel Dörfler BMessage *message = new BMessage(POP_RESOLUTION_MSG); 221*a10cf76eSAxel Dörfler message->AddInt32("width", mode.width); 222*a10cf76eSAxel Dörfler message->AddInt32("height", mode.height); 223*a10cf76eSAxel Dörfler 224*a10cf76eSAxel Dörfler BString name; 225*a10cf76eSAxel Dörfler name << mode.width << " x " << mode.height; 226*a10cf76eSAxel Dörfler 227*a10cf76eSAxel Dörfler fResolutionMenu->AddItem(new BMenuItem(name.String(), message)); 228*a10cf76eSAxel Dörfler } 229*a10cf76eSAxel Dörfler 230*a10cf76eSAxel Dörfler rect.Set(33.0, 30.0, 171.0, 48.0); 231*a10cf76eSAxel Dörfler fResolutionField = new BMenuField(rect, "ResolutionMenu", "Resolution:", 232*a10cf76eSAxel Dörfler fResolutionMenu, true); 233*a10cf76eSAxel Dörfler fResolutionField->SetDivider(55.0); 234*a10cf76eSAxel Dörfler controlsBox->AddChild(fResolutionField); 235*a10cf76eSAxel Dörfler 236*a10cf76eSAxel Dörfler fColorsMenu = new BPopUpMenu("colors", true, true); 237*a10cf76eSAxel Dörfler 238*a10cf76eSAxel Dörfler for (int32 i = 0; i < kColorSpaceCount; i++) { 239*a10cf76eSAxel Dörfler BMessage *message = new BMessage(POP_COLORS_MSG); 240*a10cf76eSAxel Dörfler message->AddInt32("bits_per_pixel", kColorSpaces[i].bits_per_pixel); 241*a10cf76eSAxel Dörfler message->AddInt32("space", kColorSpaces[i].space); 242*a10cf76eSAxel Dörfler 243*a10cf76eSAxel Dörfler fColorsMenu->AddItem(new BMenuItem(kColorSpaces[i].label, message)); 244*a10cf76eSAxel Dörfler } 245*a10cf76eSAxel Dörfler 246*a10cf76eSAxel Dörfler rect.Set(50.0, 58.0, 171.0, 76.0); 247*a10cf76eSAxel Dörfler fColorsField = new BMenuField(rect, "ColorsMenu", "Colors:", fColorsMenu, true); 248*a10cf76eSAxel Dörfler fColorsField->SetDivider(38.0); 249*a10cf76eSAxel Dörfler controlsBox->AddChild(fColorsField); 250*a10cf76eSAxel Dörfler 251*a10cf76eSAxel Dörfler fRefreshMenu = new BPopUpMenu("refresh rate", true, true); 252*a10cf76eSAxel Dörfler 253*a10cf76eSAxel Dörfler #ifdef USE_FIXED_REFRESH 254*a10cf76eSAxel Dörfler for (int32 i = 0; i < kRefreshRateCount; ++i) { 255*a10cf76eSAxel Dörfler BString name; 256*a10cf76eSAxel Dörfler name << kRefreshRates[i] << " Hz"; 257*a10cf76eSAxel Dörfler 258*a10cf76eSAxel Dörfler BMessage *message = new BMessage(POP_REFRESH_MSG); 259*a10cf76eSAxel Dörfler message->AddFloat("refresh", kRefreshRates[i]); 260*a10cf76eSAxel Dörfler 261*a10cf76eSAxel Dörfler fRefreshMenu->AddItem(new BMenuItem(name.String(), message)); 262*a10cf76eSAxel Dörfler } 263*a10cf76eSAxel Dörfler #endif 264*a10cf76eSAxel Dörfler 265*a10cf76eSAxel Dörfler BMessage *message = new BMessage(POP_OTHER_REFRESH_MSG); 266*a10cf76eSAxel Dörfler 267*a10cf76eSAxel Dörfler fOtherRefresh = new BMenuItem("Other" B_UTF8_ELLIPSIS, message); 268*a10cf76eSAxel Dörfler fRefreshMenu->AddItem(fOtherRefresh); 269*a10cf76eSAxel Dörfler 270*a10cf76eSAxel Dörfler rect.Set(19.0, 86.0, 171.0, 104.0); 271*a10cf76eSAxel Dörfler fRefreshField = new BMenuField(rect, "RefreshMenu", "Refresh Rate:", fRefreshMenu, true); 272*a10cf76eSAxel Dörfler fRefreshField->SetDivider(69.0); 273*a10cf76eSAxel Dörfler controlsBox->AddChild(fRefreshField); 274*a10cf76eSAxel Dörfler 275*a10cf76eSAxel Dörfler view->AddChild(controlsBox); 276*a10cf76eSAxel Dörfler 277*a10cf76eSAxel Dörfler // enlarged area for multi-monitor settings 278*a10cf76eSAxel Dörfler { 279*a10cf76eSAxel Dörfler bool dummy; 280*a10cf76eSAxel Dörfler uint32 dummy32; 281*a10cf76eSAxel Dörfler bool multiMonSupport; 282*a10cf76eSAxel Dörfler bool useLaptopPanelSupport; 283*a10cf76eSAxel Dörfler bool tvStandardSupport; 284*a10cf76eSAxel Dörfler 285*a10cf76eSAxel Dörfler multiMonSupport = TestMultiMonSupport(&screen) == B_OK; 286*a10cf76eSAxel Dörfler useLaptopPanelSupport = GetUseLaptopPanel(&screen, &dummy) == B_OK; 287*a10cf76eSAxel Dörfler tvStandardSupport = GetTVStandard(&screen, &dummy32) == B_OK; 288*a10cf76eSAxel Dörfler 289*a10cf76eSAxel Dörfler // even if there is no support, we still create all controls 290*a10cf76eSAxel Dörfler // to make sure we don't access NULL pointers later on 291*a10cf76eSAxel Dörfler if (multiMonSupport) { 292*a10cf76eSAxel Dörfler fApplyButton->MoveTo(275, 114); 293*a10cf76eSAxel Dörfler controlsBox->ResizeTo(366, 148); 294*a10cf76eSAxel Dörfler ResizeTo(556, 202); 295*a10cf76eSAxel Dörfler } 296*a10cf76eSAxel Dörfler 297*a10cf76eSAxel Dörfler fCombineMenu = new BPopUpMenu("CombineDisplays", true, true); 298*a10cf76eSAxel Dörfler 299*a10cf76eSAxel Dörfler for (int32 i = 0; i < kCombineModeCount; i++) { 300*a10cf76eSAxel Dörfler message = new BMessage(POP_COMBINE_DISPLAYS_MSG); 301*a10cf76eSAxel Dörfler message->AddInt32("mode", kCombineModes[i].mode); 302*a10cf76eSAxel Dörfler 303*a10cf76eSAxel Dörfler fCombineMenu->AddItem(new BMenuItem(kCombineModes[i].name, message)); 304*a10cf76eSAxel Dörfler } 305*a10cf76eSAxel Dörfler 306*a10cf76eSAxel Dörfler rect.Set(185, 30, 356, 48); 307*a10cf76eSAxel Dörfler BMenuField* menuField = new BMenuField(rect, "CombineMenu", 308*a10cf76eSAxel Dörfler "Combine Displays:", fCombineMenu, true); 309*a10cf76eSAxel Dörfler menuField->SetDivider(90); 310*a10cf76eSAxel Dörfler controlsBox->AddChild(menuField); 311*a10cf76eSAxel Dörfler 312*a10cf76eSAxel Dörfler if (!multiMonSupport) 313*a10cf76eSAxel Dörfler menuField->Hide(); 314*a10cf76eSAxel Dörfler 315*a10cf76eSAxel Dörfler fSwapDisplaysMenu = new BPopUpMenu("SwapDisplays", true, true); 316*a10cf76eSAxel Dörfler 317*a10cf76eSAxel Dörfler // !order is important - we rely that boolean value == idx 318*a10cf76eSAxel Dörfler message = new BMessage(POP_SWAP_DISPLAYS_MSG); 319*a10cf76eSAxel Dörfler message->AddBool("swap", false); 320*a10cf76eSAxel Dörfler fSwapDisplaysMenu->AddItem(new BMenuItem("no", message)); 321*a10cf76eSAxel Dörfler 322*a10cf76eSAxel Dörfler message = new BMessage(POP_SWAP_DISPLAYS_MSG); 323*a10cf76eSAxel Dörfler message->AddBool("swap", true); 324*a10cf76eSAxel Dörfler fSwapDisplaysMenu->AddItem(new BMenuItem("yes", message)); 325*a10cf76eSAxel Dörfler 326*a10cf76eSAxel Dörfler rect.Set(199, 58, 356, 76); 327*a10cf76eSAxel Dörfler menuField = new BMenuField(rect, "SwapMenu", "Swap Displays:", 328*a10cf76eSAxel Dörfler fSwapDisplaysMenu, true); 329*a10cf76eSAxel Dörfler menuField->SetDivider(76); 330*a10cf76eSAxel Dörfler 331*a10cf76eSAxel Dörfler controlsBox->AddChild(menuField); 332*a10cf76eSAxel Dörfler if (!multiMonSupport) 333*a10cf76eSAxel Dörfler menuField->Hide(); 334*a10cf76eSAxel Dörfler 335*a10cf76eSAxel Dörfler fUseLaptopPanelMenu = new BPopUpMenu("UseLaptopPanel", true, true); 336*a10cf76eSAxel Dörfler 337*a10cf76eSAxel Dörfler // !order is important - we rely that boolean value == idx 338*a10cf76eSAxel Dörfler message = new BMessage(POP_USE_LAPTOP_PANEL_MSG); 339*a10cf76eSAxel Dörfler message->AddBool("use", false); 340*a10cf76eSAxel Dörfler fUseLaptopPanelMenu->AddItem(new BMenuItem("if needed", message)); 341*a10cf76eSAxel Dörfler 342*a10cf76eSAxel Dörfler message = new BMessage(POP_USE_LAPTOP_PANEL_MSG); 343*a10cf76eSAxel Dörfler message->AddBool("use", true); 344*a10cf76eSAxel Dörfler fUseLaptopPanelMenu->AddItem(new BMenuItem("always", message)); 345*a10cf76eSAxel Dörfler 346*a10cf76eSAxel Dörfler rect.Set(184, 86, 356, 104); 347*a10cf76eSAxel Dörfler menuField = new BMenuField(rect, "UseLaptopPanel", "Use Laptop Panel:", 348*a10cf76eSAxel Dörfler fUseLaptopPanelMenu, true); 349*a10cf76eSAxel Dörfler menuField->SetDivider(91); 350*a10cf76eSAxel Dörfler 351*a10cf76eSAxel Dörfler controlsBox->AddChild(menuField); 352*a10cf76eSAxel Dörfler if (!useLaptopPanelSupport) 353*a10cf76eSAxel Dörfler menuField->Hide(); 354*a10cf76eSAxel Dörfler 355*a10cf76eSAxel Dörfler fTVStandardMenu = new BPopUpMenu("TVStandard", true, true); 356*a10cf76eSAxel Dörfler 357*a10cf76eSAxel Dörfler // arbitrary limit 358*a10cf76eSAxel Dörfler uint32 i; 359*a10cf76eSAxel Dörfler for (i = 0; i < 100; ++i) { 360*a10cf76eSAxel Dörfler uint32 mode; 361*a10cf76eSAxel Dörfler 362*a10cf76eSAxel Dörfler if (GetNthSupportedTVStandard(&screen, i, &mode) != B_OK) 363*a10cf76eSAxel Dörfler break; 364*a10cf76eSAxel Dörfler 365*a10cf76eSAxel Dörfler BString name = tv_standard_to_string(mode); 366*a10cf76eSAxel Dörfler 367*a10cf76eSAxel Dörfler message = new BMessage(POP_TV_STANDARD_MSG); 368*a10cf76eSAxel Dörfler message->AddInt32("tv_standard", mode); 369*a10cf76eSAxel Dörfler 370*a10cf76eSAxel Dörfler fTVStandardMenu->AddItem(new BMenuItem(name.String(), message)); 371*a10cf76eSAxel Dörfler } 372*a10cf76eSAxel Dörfler 373*a10cf76eSAxel Dörfler rect.Set(15, 114, 171, 132); 374*a10cf76eSAxel Dörfler menuField = new BMenuField(rect, "tv standard", "Video Format:", 375*a10cf76eSAxel Dörfler fTVStandardMenu, true); 376*a10cf76eSAxel Dörfler menuField->SetDivider(73); 377*a10cf76eSAxel Dörfler 378*a10cf76eSAxel Dörfler if (!tvStandardSupport || i == 0) 379*a10cf76eSAxel Dörfler menuField->Hide(); 380*a10cf76eSAxel Dörfler 381*a10cf76eSAxel Dörfler controlsBox->AddChild(menuField); 382*a10cf76eSAxel Dörfler } 383*a10cf76eSAxel Dörfler 384*a10cf76eSAxel Dörfler rect.Set(10.0, 167, 100.0, 200.0); 385*a10cf76eSAxel Dörfler fDefaultsButton = new BButton(rect, "DefaultsButton", "Defaults", 386*a10cf76eSAxel Dörfler new BMessage(BUTTON_DEFAULTS_MSG)); 387*a10cf76eSAxel Dörfler fDefaultsButton->ResizeToPreferred(); 388*a10cf76eSAxel Dörfler view->AddChild(fDefaultsButton); 389*a10cf76eSAxel Dörfler 390*a10cf76eSAxel Dörfler rect.Set(95.0, 167, 160.0, 200.0); 391*a10cf76eSAxel Dörfler fRevertButton = new BButton(rect, "RevertButton", "Revert", 392*a10cf76eSAxel Dörfler new BMessage(BUTTON_REVERT_MSG)); 393*a10cf76eSAxel Dörfler fRevertButton->ResizeToPreferred(); 394*a10cf76eSAxel Dörfler fRevertButton->SetEnabled(false); 395*a10cf76eSAxel Dörfler view->AddChild(fRevertButton); 396*a10cf76eSAxel Dörfler 397*a10cf76eSAxel Dörfler UpdateControls(); 398*a10cf76eSAxel Dörfler } 399*a10cf76eSAxel Dörfler 400*a10cf76eSAxel Dörfler 401*a10cf76eSAxel Dörfler ScreenWindow::~ScreenWindow() 402*a10cf76eSAxel Dörfler { 403*a10cf76eSAxel Dörfler delete fSettings; 404*a10cf76eSAxel Dörfler } 405*a10cf76eSAxel Dörfler 406*a10cf76eSAxel Dörfler 407*a10cf76eSAxel Dörfler bool 408*a10cf76eSAxel Dörfler ScreenWindow::QuitRequested() 409*a10cf76eSAxel Dörfler { 410*a10cf76eSAxel Dörfler fSettings->SetWindowFrame(Frame()); 411*a10cf76eSAxel Dörfler be_app->PostMessage(B_QUIT_REQUESTED); 412*a10cf76eSAxel Dörfler 413*a10cf76eSAxel Dörfler return BWindow::QuitRequested(); 414*a10cf76eSAxel Dörfler } 415*a10cf76eSAxel Dörfler 416*a10cf76eSAxel Dörfler 417*a10cf76eSAxel Dörfler /** update resolution list according to combine mode 418*a10cf76eSAxel Dörfler * (some resolution may not be combinable due to memory restrictions) 419*a10cf76eSAxel Dörfler */ 420*a10cf76eSAxel Dörfler 421*a10cf76eSAxel Dörfler void 422*a10cf76eSAxel Dörfler ScreenWindow::CheckResolutionMenu() 423*a10cf76eSAxel Dörfler { 424*a10cf76eSAxel Dörfler for (int32 i = 0; i < fResolutionMenu->CountItems(); i++) 425*a10cf76eSAxel Dörfler fResolutionMenu->ItemAt(i)->SetEnabled(false); 426*a10cf76eSAxel Dörfler 427*a10cf76eSAxel Dörfler for (int32 i = 0; i < fScreenMode.CountModes(); i++) { 428*a10cf76eSAxel Dörfler screen_mode mode = fScreenMode.ModeAt(i); 429*a10cf76eSAxel Dörfler if (mode.combine != fSelected.combine) 430*a10cf76eSAxel Dörfler continue; 431*a10cf76eSAxel Dörfler 432*a10cf76eSAxel Dörfler BString name; 433*a10cf76eSAxel Dörfler name << mode.width << " x " << mode.height; 434*a10cf76eSAxel Dörfler 435*a10cf76eSAxel Dörfler BMenuItem *item = fResolutionMenu->FindItem(name.String()); 436*a10cf76eSAxel Dörfler if (item != NULL) 437*a10cf76eSAxel Dörfler item->SetEnabled(true); 438*a10cf76eSAxel Dörfler } 439*a10cf76eSAxel Dörfler } 440*a10cf76eSAxel Dörfler 441*a10cf76eSAxel Dörfler 442*a10cf76eSAxel Dörfler /** update color and refresh options according to current mode 443*a10cf76eSAxel Dörfler * (a color space is made active if there is any mode with 444*a10cf76eSAxel Dörfler * given resolution and this colour space; same applies for 445*a10cf76eSAxel Dörfler * refresh rate, though "Other…" is always possible) 446*a10cf76eSAxel Dörfler */ 447*a10cf76eSAxel Dörfler 448*a10cf76eSAxel Dörfler void 449*a10cf76eSAxel Dörfler ScreenWindow::CheckColorMenu() 450*a10cf76eSAxel Dörfler { 451*a10cf76eSAxel Dörfler for (int32 i = 0; i < kColorSpaceCount; i++) { 452*a10cf76eSAxel Dörfler bool supported = false; 453*a10cf76eSAxel Dörfler 454*a10cf76eSAxel Dörfler for (int32 j = 0; j < fScreenMode.CountModes(); j++) { 455*a10cf76eSAxel Dörfler screen_mode mode = fScreenMode.ModeAt(j); 456*a10cf76eSAxel Dörfler 457*a10cf76eSAxel Dörfler if (fSelected.width == mode.width 458*a10cf76eSAxel Dörfler && fSelected.height == mode.height 459*a10cf76eSAxel Dörfler && kColorSpaces[i].space == mode.space 460*a10cf76eSAxel Dörfler && fSelected.combine == mode.combine) { 461*a10cf76eSAxel Dörfler supported = true; 462*a10cf76eSAxel Dörfler break; 463*a10cf76eSAxel Dörfler } 464*a10cf76eSAxel Dörfler } 465*a10cf76eSAxel Dörfler 466*a10cf76eSAxel Dörfler BMenuItem* item = fColorsMenu->ItemAt(i); 467*a10cf76eSAxel Dörfler if (item) 468*a10cf76eSAxel Dörfler item->SetEnabled(supported); 469*a10cf76eSAxel Dörfler } 470*a10cf76eSAxel Dörfler } 471*a10cf76eSAxel Dörfler 472*a10cf76eSAxel Dörfler 473*a10cf76eSAxel Dörfler /** Enable/disable refresh options according to current mode. 474*a10cf76eSAxel Dörfler * Only needed when USE_FIXED_REFRESH is not defined. 475*a10cf76eSAxel Dörfler */ 476*a10cf76eSAxel Dörfler 477*a10cf76eSAxel Dörfler void 478*a10cf76eSAxel Dörfler ScreenWindow::CheckRefreshMenu() 479*a10cf76eSAxel Dörfler { 480*a10cf76eSAxel Dörfler #ifndef USE_FIXED_REFRESH 481*a10cf76eSAxel Dörfler // ToDo: does currently not compile! 482*a10cf76eSAxel Dörfler for (int32 i = fRefreshMenu->CountItems() - 2; i >= 0; --i) { 483*a10cf76eSAxel Dörfler delete fRefreshMenu->RemoveItem(i); 484*a10cf76eSAxel Dörfler } 485*a10cf76eSAxel Dörfler 486*a10cf76eSAxel Dörfler for (int32 i = 0; i < fModeListCount; ++i) { 487*a10cf76eSAxel Dörfler if (virtualWidth == fModeList[i].virtual_width 488*a10cf76eSAxel Dörfler && virtualHeight == fModeList[i].virtual_height 489*a10cf76eSAxel Dörfler && combine == get_combine_mode(&fModeList[i])) { 490*a10cf76eSAxel Dörfler BString name; 491*a10cf76eSAxel Dörfler BMenuItem *item; 492*a10cf76eSAxel Dörfler 493*a10cf76eSAxel Dörfler int32 refresh10 = get_refresh10(fModeList[i]); 494*a10cf76eSAxel Dörfler refresh10_to_string(name, refresh10); 495*a10cf76eSAxel Dörfler 496*a10cf76eSAxel Dörfler item = fRefreshMenu->FindItem(name.String()); 497*a10cf76eSAxel Dörfler if (item == NULL) { 498*a10cf76eSAxel Dörfler BMessage *msg = new BMessage(POP_REFRESH_MSG); 499*a10cf76eSAxel Dörfler msg->AddFloat("refresh", refresh); 500*a10cf76eSAxel Dörfler 501*a10cf76eSAxel Dörfler fRefreshMenu->AddItem(new BMenuItem(name.String(), msg), 502*a10cf76eSAxel Dörfler fRefreshMenu->CountItems() - 1); 503*a10cf76eSAxel Dörfler } 504*a10cf76eSAxel Dörfler } 505*a10cf76eSAxel Dörfler } 506*a10cf76eSAxel Dörfler #endif 507*a10cf76eSAxel Dörfler 508*a10cf76eSAxel Dörfler // TBD: some drivers lack many refresh rates; still, they 509*a10cf76eSAxel Dörfler // can be used by generating the mode manually 510*a10cf76eSAxel Dörfler /* 511*a10cf76eSAxel Dörfler for( i = 0; i < sizeof( refresh_list ) / sizeof( refresh_list[0] ); ++i ) { 512*a10cf76eSAxel Dörfler BMenuItem *item; 513*a10cf76eSAxel Dörfler bool supported = false; 514*a10cf76eSAxel Dörfler 515*a10cf76eSAxel Dörfler for( j = 0; j < fModeListCount; ++j ) { 516*a10cf76eSAxel Dörfler if( width == fModeList[j].virtual_width && 517*a10cf76eSAxel Dörfler height == fModeList[j].virtual_height && 518*a10cf76eSAxel Dörfler refresh_list[i].refresh * 10 == getModeRefresh10( &fModeList[j] )) 519*a10cf76eSAxel Dörfler { 520*a10cf76eSAxel Dörfler supported = true; 521*a10cf76eSAxel Dörfler break; 522*a10cf76eSAxel Dörfler } 523*a10cf76eSAxel Dörfler } 524*a10cf76eSAxel Dörfler 525*a10cf76eSAxel Dörfler item = fRefreshMenu->ItemAt( i ); 526*a10cf76eSAxel Dörfler if( item ) 527*a10cf76eSAxel Dörfler item->SetEnabled( supported ); 528*a10cf76eSAxel Dörfler } 529*a10cf76eSAxel Dörfler */ 530*a10cf76eSAxel Dörfler } 531*a10cf76eSAxel Dörfler 532*a10cf76eSAxel Dörfler 533*a10cf76eSAxel Dörfler /** activate appropriate menu item according to selected refresh rate */ 534*a10cf76eSAxel Dörfler 535*a10cf76eSAxel Dörfler void 536*a10cf76eSAxel Dörfler ScreenWindow::UpdateRefreshControl() 537*a10cf76eSAxel Dörfler { 538*a10cf76eSAxel Dörfler BString string; 539*a10cf76eSAxel Dörfler refresh_rate_to_string(fSelected.refresh, string); 540*a10cf76eSAxel Dörfler 541*a10cf76eSAxel Dörfler BMenuItem* item = fRefreshMenu->FindItem(string.String()); 542*a10cf76eSAxel Dörfler if (item) { 543*a10cf76eSAxel Dörfler if (!item->IsMarked()) 544*a10cf76eSAxel Dörfler item->SetMarked(true); 545*a10cf76eSAxel Dörfler // "Other…" items only contains a refresh rate when active 546*a10cf76eSAxel Dörfler fOtherRefresh->SetLabel("Other…"); 547*a10cf76eSAxel Dörfler return; 548*a10cf76eSAxel Dörfler } 549*a10cf76eSAxel Dörfler 550*a10cf76eSAxel Dörfler // this is a non-standard refresh rate 551*a10cf76eSAxel Dörfler 552*a10cf76eSAxel Dörfler fOtherRefresh->Message()->ReplaceFloat("refresh", fSelected.refresh); 553*a10cf76eSAxel Dörfler fOtherRefresh->SetMarked(true); 554*a10cf76eSAxel Dörfler 555*a10cf76eSAxel Dörfler fRefreshMenu->Superitem()->SetLabel(string.String()); 556*a10cf76eSAxel Dörfler 557*a10cf76eSAxel Dörfler string.Append("/Other" B_UTF8_ELLIPSIS); 558*a10cf76eSAxel Dörfler fOtherRefresh->SetLabel(string.String()); 559*a10cf76eSAxel Dörfler } 560*a10cf76eSAxel Dörfler 561*a10cf76eSAxel Dörfler 562*a10cf76eSAxel Dörfler void 563*a10cf76eSAxel Dörfler ScreenWindow::UpdateMonitorView() 564*a10cf76eSAxel Dörfler { 565*a10cf76eSAxel Dörfler BMessage updateMessage(UPDATE_DESKTOP_MSG); 566*a10cf76eSAxel Dörfler updateMessage.AddInt32("width", fSelected.width); 567*a10cf76eSAxel Dörfler updateMessage.AddInt32("height", fSelected.height); 568*a10cf76eSAxel Dörfler 569*a10cf76eSAxel Dörfler PostMessage(&updateMessage, fMonitorView); 570*a10cf76eSAxel Dörfler } 571*a10cf76eSAxel Dörfler 572*a10cf76eSAxel Dörfler 573*a10cf76eSAxel Dörfler void 574*a10cf76eSAxel Dörfler ScreenWindow::UpdateControls() 575*a10cf76eSAxel Dörfler { 576*a10cf76eSAxel Dörfler BMenuItem* item = fSwapDisplaysMenu->ItemAt((int32)fSelected.swap_displays); 577*a10cf76eSAxel Dörfler if (item && !item->IsMarked()) 578*a10cf76eSAxel Dörfler item->SetMarked(true); 579*a10cf76eSAxel Dörfler 580*a10cf76eSAxel Dörfler item = fUseLaptopPanelMenu->ItemAt((int32)fSelected.use_laptop_panel); 581*a10cf76eSAxel Dörfler if (item && !item->IsMarked()) 582*a10cf76eSAxel Dörfler item->SetMarked(true); 583*a10cf76eSAxel Dörfler 584*a10cf76eSAxel Dörfler for (int32 i = 0; i < fTVStandardMenu->CountItems(); i++) { 585*a10cf76eSAxel Dörfler item = fTVStandardMenu->ItemAt(i); 586*a10cf76eSAxel Dörfler 587*a10cf76eSAxel Dörfler uint32 tvStandard; 588*a10cf76eSAxel Dörfler item->Message()->FindInt32("tv_standard", (int32 *)&tvStandard); 589*a10cf76eSAxel Dörfler if (tvStandard == fSelected.tv_standard) { 590*a10cf76eSAxel Dörfler if (!item->IsMarked()) 591*a10cf76eSAxel Dörfler item->SetMarked(true); 592*a10cf76eSAxel Dörfler break; 593*a10cf76eSAxel Dörfler } 594*a10cf76eSAxel Dörfler } 595*a10cf76eSAxel Dörfler 596*a10cf76eSAxel Dörfler CheckResolutionMenu(); 597*a10cf76eSAxel Dörfler CheckColorMenu(); 598*a10cf76eSAxel Dörfler CheckRefreshMenu(); 599*a10cf76eSAxel Dörfler 600*a10cf76eSAxel Dörfler BString string; 601*a10cf76eSAxel Dörfler resolution_to_string(fSelected, string); 602*a10cf76eSAxel Dörfler item = fResolutionMenu->FindItem(string.String()); 603*a10cf76eSAxel Dörfler 604*a10cf76eSAxel Dörfler if (item != NULL) { 605*a10cf76eSAxel Dörfler if (!item->IsMarked()) 606*a10cf76eSAxel Dörfler item->SetMarked(true); 607*a10cf76eSAxel Dörfler } else { 608*a10cf76eSAxel Dörfler // this is bad luck - if mode has been set via screen references, 609*a10cf76eSAxel Dörfler // this case cannot occur; there are three possible solutions: 610*a10cf76eSAxel Dörfler // 1. add a new resolution to list 611*a10cf76eSAxel Dörfler // - we had to remove it as soon as a "valid" one is selected 612*a10cf76eSAxel Dörfler // - we don't know which frequencies/bit depths are supported 613*a10cf76eSAxel Dörfler // - as long as we haven't the GMT formula to create 614*a10cf76eSAxel Dörfler // parameters for any resolution given, we cannot 615*a10cf76eSAxel Dörfler // really set current mode - it's just not in the list 616*a10cf76eSAxel Dörfler // 2. choose nearest resolution 617*a10cf76eSAxel Dörfler // - probably a good idea, but implies coding and testing 618*a10cf76eSAxel Dörfler // 3. choose lowest resolution 619*a10cf76eSAxel Dörfler // - do you really think we are so lazy? yes, we are 620*a10cf76eSAxel Dörfler item = fResolutionMenu->ItemAt(0); 621*a10cf76eSAxel Dörfler if (item) 622*a10cf76eSAxel Dörfler item->SetMarked(true); 623*a10cf76eSAxel Dörfler 624*a10cf76eSAxel Dörfler // okay - at least we set menu label to active resolution 625*a10cf76eSAxel Dörfler fResolutionMenu->Superitem()->SetLabel(string.String()); 626*a10cf76eSAxel Dörfler } 627*a10cf76eSAxel Dörfler 628*a10cf76eSAxel Dörfler // mark active combine mode 629*a10cf76eSAxel Dörfler for (int32 i = 0; i < kCombineModeCount; i++) { 630*a10cf76eSAxel Dörfler if (kCombineModes[i].mode == fSelected.combine) { 631*a10cf76eSAxel Dörfler item = fCombineMenu->ItemAt(i); 632*a10cf76eSAxel Dörfler if (item && !item->IsMarked()) 633*a10cf76eSAxel Dörfler item->SetMarked(true); 634*a10cf76eSAxel Dörfler break; 635*a10cf76eSAxel Dörfler } 636*a10cf76eSAxel Dörfler } 637*a10cf76eSAxel Dörfler 638*a10cf76eSAxel Dörfler item = fColorsMenu->ItemAt(0); 639*a10cf76eSAxel Dörfler 640*a10cf76eSAxel Dörfler for (int32 i = kColorSpaceCount; i-- > 0;) { 641*a10cf76eSAxel Dörfler if (kColorSpaces[i].space == fSelected.space) { 642*a10cf76eSAxel Dörfler item = fColorsMenu->ItemAt(i); 643*a10cf76eSAxel Dörfler break; 644*a10cf76eSAxel Dörfler } 645*a10cf76eSAxel Dörfler } 646*a10cf76eSAxel Dörfler 647*a10cf76eSAxel Dörfler if (item && !item->IsMarked()) 648*a10cf76eSAxel Dörfler item->SetMarked(true); 649*a10cf76eSAxel Dörfler 650*a10cf76eSAxel Dörfler string.Truncate(0); 651*a10cf76eSAxel Dörfler string << fSelected.BitsPerPixel() << " Bits/Pixel"; 652*a10cf76eSAxel Dörfler if (string != fColorsMenu->Superitem()->Label()) 653*a10cf76eSAxel Dörfler fColorsMenu->Superitem()->SetLabel(string.String()); 654*a10cf76eSAxel Dörfler 655*a10cf76eSAxel Dörfler UpdateMonitorView(); 656*a10cf76eSAxel Dörfler UpdateRefreshControl(); 657*a10cf76eSAxel Dörfler 658*a10cf76eSAxel Dörfler CheckApplyEnabled(); 659*a10cf76eSAxel Dörfler } 660*a10cf76eSAxel Dörfler 661*a10cf76eSAxel Dörfler 662*a10cf76eSAxel Dörfler /** reflect active mode in chosen settings */ 663*a10cf76eSAxel Dörfler 664*a10cf76eSAxel Dörfler void 665*a10cf76eSAxel Dörfler ScreenWindow::UpdateActiveMode() 666*a10cf76eSAxel Dörfler { 667*a10cf76eSAxel Dörfler // usually, this function gets called after a mode 668*a10cf76eSAxel Dörfler // has been set manually; still, as the graphics driver 669*a10cf76eSAxel Dörfler // is free to fiddle with mode passed, we better ask 670*a10cf76eSAxel Dörfler // what kind of mode we actually got 671*a10cf76eSAxel Dörfler fScreenMode.Get(fActive); 672*a10cf76eSAxel Dörfler fSelected = fActive; 673*a10cf76eSAxel Dörfler 674*a10cf76eSAxel Dörfler UpdateControls(); 675*a10cf76eSAxel Dörfler } 676*a10cf76eSAxel Dörfler 677*a10cf76eSAxel Dörfler 678*a10cf76eSAxel Dörfler void 679*a10cf76eSAxel Dörfler ScreenWindow::ScreenChanged(BRect frame, color_space mode) 680*a10cf76eSAxel Dörfler { 681*a10cf76eSAxel Dörfler // move window on screen, if necessary 682*a10cf76eSAxel Dörfler if (frame.right <= Frame().right 683*a10cf76eSAxel Dörfler && frame.bottom <= Frame().bottom) { 684*a10cf76eSAxel Dörfler MoveTo((frame.Width() - Frame().Width()) / 2, 685*a10cf76eSAxel Dörfler (frame.Height() - Frame().Height()) / 2); 686*a10cf76eSAxel Dörfler } 687*a10cf76eSAxel Dörfler } 688*a10cf76eSAxel Dörfler 689*a10cf76eSAxel Dörfler 690*a10cf76eSAxel Dörfler void 691*a10cf76eSAxel Dörfler ScreenWindow::WorkspaceActivated(int32 workspace, bool state) 692*a10cf76eSAxel Dörfler { 693*a10cf76eSAxel Dörfler if (fChangingAllWorkspaces) { 694*a10cf76eSAxel Dörfler // we're currently changing all workspaces, so there is no need 695*a10cf76eSAxel Dörfler // to update the interface 696*a10cf76eSAxel Dörfler return; 697*a10cf76eSAxel Dörfler } 698*a10cf76eSAxel Dörfler 699*a10cf76eSAxel Dörfler fScreenMode.Get(fOriginal); 700*a10cf76eSAxel Dörfler fScreenMode.UpdateOriginalMode(); 701*a10cf76eSAxel Dörfler 702*a10cf76eSAxel Dörfler // only override current settings if they have not been changed yet 703*a10cf76eSAxel Dörfler if (fSelected == fActive) 704*a10cf76eSAxel Dörfler UpdateActiveMode(); 705*a10cf76eSAxel Dörfler 706*a10cf76eSAxel Dörfler PostMessage(new BMessage(UPDATE_DESKTOP_COLOR_MSG), fMonitorView); 707*a10cf76eSAxel Dörfler } 708*a10cf76eSAxel Dörfler 709*a10cf76eSAxel Dörfler 710*a10cf76eSAxel Dörfler void 711*a10cf76eSAxel Dörfler ScreenWindow::MessageReceived(BMessage* message) 712*a10cf76eSAxel Dörfler { 713*a10cf76eSAxel Dörfler switch (message->what) { 714*a10cf76eSAxel Dörfler case WORKSPACE_CHECK_MSG: 715*a10cf76eSAxel Dörfler CheckApplyEnabled(); 716*a10cf76eSAxel Dörfler break; 717*a10cf76eSAxel Dörfler 718*a10cf76eSAxel Dörfler case POP_WORKSPACE_CHANGED_MSG: 719*a10cf76eSAxel Dörfler { 720*a10cf76eSAxel Dörfler int32 index; 721*a10cf76eSAxel Dörfler if (message->FindInt32("index", &index) == B_OK) 722*a10cf76eSAxel Dörfler set_workspace_count(index + 1); 723*a10cf76eSAxel Dörfler break; 724*a10cf76eSAxel Dörfler } 725*a10cf76eSAxel Dörfler 726*a10cf76eSAxel Dörfler case POP_RESOLUTION_MSG: 727*a10cf76eSAxel Dörfler { 728*a10cf76eSAxel Dörfler message->FindInt32("width", &fSelected.width); 729*a10cf76eSAxel Dörfler message->FindInt32("height", &fSelected.height); 730*a10cf76eSAxel Dörfler 731*a10cf76eSAxel Dörfler CheckColorMenu(); 732*a10cf76eSAxel Dörfler CheckRefreshMenu(); 733*a10cf76eSAxel Dörfler 734*a10cf76eSAxel Dörfler UpdateMonitorView(); 735*a10cf76eSAxel Dörfler UpdateRefreshControl(); 736*a10cf76eSAxel Dörfler 737*a10cf76eSAxel Dörfler CheckApplyEnabled(); 738*a10cf76eSAxel Dörfler break; 739*a10cf76eSAxel Dörfler } 740*a10cf76eSAxel Dörfler 741*a10cf76eSAxel Dörfler case POP_COLORS_MSG: 742*a10cf76eSAxel Dörfler { 743*a10cf76eSAxel Dörfler message->FindInt32("space", (int32 *)&fSelected.space); 744*a10cf76eSAxel Dörfler 745*a10cf76eSAxel Dörfler BString string; 746*a10cf76eSAxel Dörfler string << fSelected.BitsPerPixel() << " Bits/Pixel"; 747*a10cf76eSAxel Dörfler fColorsMenu->Superitem()->SetLabel(string.String()); 748*a10cf76eSAxel Dörfler 749*a10cf76eSAxel Dörfler CheckApplyEnabled(); 750*a10cf76eSAxel Dörfler break; 751*a10cf76eSAxel Dörfler } 752*a10cf76eSAxel Dörfler 753*a10cf76eSAxel Dörfler case POP_REFRESH_MSG: 754*a10cf76eSAxel Dörfler message->FindFloat("refresh", &fSelected.refresh); 755*a10cf76eSAxel Dörfler fOtherRefresh->SetLabel("Other" B_UTF8_ELLIPSIS); 756*a10cf76eSAxel Dörfler // revert "Other…" label - it might have had a refresh rate prefix 757*a10cf76eSAxel Dörfler 758*a10cf76eSAxel Dörfler CheckApplyEnabled(); 759*a10cf76eSAxel Dörfler break; 760*a10cf76eSAxel Dörfler 761*a10cf76eSAxel Dörfler case POP_OTHER_REFRESH_MSG: 762*a10cf76eSAxel Dörfler { 763*a10cf76eSAxel Dörfler // make sure menu shows something usefull 764*a10cf76eSAxel Dörfler UpdateRefreshControl(); 765*a10cf76eSAxel Dörfler 766*a10cf76eSAxel Dörfler BRect frame(Frame()); 767*a10cf76eSAxel Dörfler RefreshWindow *fRefreshWindow = new RefreshWindow(BRect(frame.left + 201.0, 768*a10cf76eSAxel Dörfler frame.top + 34.0, frame.left + 509.0, frame.top + 169.0), 769*a10cf76eSAxel Dörfler int32(fSelected.refresh * 10)); 770*a10cf76eSAxel Dörfler fRefreshWindow->Show(); 771*a10cf76eSAxel Dörfler break; 772*a10cf76eSAxel Dörfler } 773*a10cf76eSAxel Dörfler 774*a10cf76eSAxel Dörfler case SET_CUSTOM_REFRESH_MSG: 775*a10cf76eSAxel Dörfler { 776*a10cf76eSAxel Dörfler // user pressed "done" in "Other…" refresh dialog; 777*a10cf76eSAxel Dörfler // select the refresh rate chosen 778*a10cf76eSAxel Dörfler message->FindFloat("refresh", &fSelected.refresh); 779*a10cf76eSAxel Dörfler 780*a10cf76eSAxel Dörfler UpdateRefreshControl(); 781*a10cf76eSAxel Dörfler CheckApplyEnabled(); 782*a10cf76eSAxel Dörfler break; 783*a10cf76eSAxel Dörfler } 784*a10cf76eSAxel Dörfler 785*a10cf76eSAxel Dörfler case POP_COMBINE_DISPLAYS_MSG: 786*a10cf76eSAxel Dörfler { 787*a10cf76eSAxel Dörfler // new combine mode has bee chosen 788*a10cf76eSAxel Dörfler int32 mode; 789*a10cf76eSAxel Dörfler if (message->FindInt32("mode", &mode) == B_OK) 790*a10cf76eSAxel Dörfler fSelected.combine = (combine_mode)mode; 791*a10cf76eSAxel Dörfler 792*a10cf76eSAxel Dörfler CheckResolutionMenu(); 793*a10cf76eSAxel Dörfler CheckApplyEnabled(); 794*a10cf76eSAxel Dörfler break; 795*a10cf76eSAxel Dörfler } 796*a10cf76eSAxel Dörfler 797*a10cf76eSAxel Dörfler case POP_SWAP_DISPLAYS_MSG: 798*a10cf76eSAxel Dörfler message->FindBool("swap", &fSelected.swap_displays); 799*a10cf76eSAxel Dörfler CheckApplyEnabled(); 800*a10cf76eSAxel Dörfler break; 801*a10cf76eSAxel Dörfler 802*a10cf76eSAxel Dörfler case POP_USE_LAPTOP_PANEL_MSG: 803*a10cf76eSAxel Dörfler message->FindBool("use", &fSelected.use_laptop_panel); 804*a10cf76eSAxel Dörfler CheckApplyEnabled(); 805*a10cf76eSAxel Dörfler break; 806*a10cf76eSAxel Dörfler 807*a10cf76eSAxel Dörfler case POP_TV_STANDARD_MSG: 808*a10cf76eSAxel Dörfler message->FindInt32("tv_standard", (int32 *)&fSelected.tv_standard); 809*a10cf76eSAxel Dörfler CheckApplyEnabled(); 810*a10cf76eSAxel Dörfler break; 811*a10cf76eSAxel Dörfler 812*a10cf76eSAxel Dörfler case BUTTON_DEFAULTS_MSG: 813*a10cf76eSAxel Dörfler { 814*a10cf76eSAxel Dörfler fSelected.width = 640; 815*a10cf76eSAxel Dörfler fSelected.height = 480; 816*a10cf76eSAxel Dörfler fSelected.space = B_CMAP8; 817*a10cf76eSAxel Dörfler fSelected.refresh = 60.0; 818*a10cf76eSAxel Dörfler fSelected.combine = kCombineDisable; 819*a10cf76eSAxel Dörfler fSelected.swap_displays = false; 820*a10cf76eSAxel Dörfler fSelected.use_laptop_panel = false; 821*a10cf76eSAxel Dörfler fSelected.tv_standard = 0; 822*a10cf76eSAxel Dörfler 823*a10cf76eSAxel Dörfler UpdateControls(); 824*a10cf76eSAxel Dörfler break; 825*a10cf76eSAxel Dörfler } 826*a10cf76eSAxel Dörfler 827*a10cf76eSAxel Dörfler case BUTTON_REVERT_MSG: 828*a10cf76eSAxel Dörfler case SET_INITIAL_MODE_MSG: 829*a10cf76eSAxel Dörfler fScreenMode.Revert(); 830*a10cf76eSAxel Dörfler UpdateActiveMode(); 831*a10cf76eSAxel Dörfler break; 832*a10cf76eSAxel Dörfler 833*a10cf76eSAxel Dörfler case BUTTON_APPLY_MSG: 834*a10cf76eSAxel Dörfler Apply(); 835*a10cf76eSAxel Dörfler break; 836*a10cf76eSAxel Dörfler 837*a10cf76eSAxel Dörfler case MAKE_INITIAL_MSG: { 838*a10cf76eSAxel Dörfler // user pressed "keep" in confirmation box; 839*a10cf76eSAxel Dörfler // select this mode in dialog and mark it as 840*a10cf76eSAxel Dörfler // previous mode; if "all workspaces" is selected, 841*a10cf76eSAxel Dörfler // distribute mode to all workspaces 842*a10cf76eSAxel Dörfler 843*a10cf76eSAxel Dörfler // use the mode that has eventually been set and 844*a10cf76eSAxel Dörfler // thus we know to be working; it can differ from 845*a10cf76eSAxel Dörfler // the mode selected by user due to hardware limitation 846*a10cf76eSAxel Dörfler display_mode newMode; 847*a10cf76eSAxel Dörfler BScreen screen(this); 848*a10cf76eSAxel Dörfler screen.GetMode(&newMode); 849*a10cf76eSAxel Dörfler 850*a10cf76eSAxel Dörfler if (fAllWorkspacesItem->IsMarked()) { 851*a10cf76eSAxel Dörfler int32 originatingWorkspace; 852*a10cf76eSAxel Dörfler 853*a10cf76eSAxel Dörfler // the original panel activates each workspace in turn; 854*a10cf76eSAxel Dörfler // this is disguisting and there is a SetMode 855*a10cf76eSAxel Dörfler // variant that accepts a workspace id, so let's take 856*a10cf76eSAxel Dörfler // this one 857*a10cf76eSAxel Dörfler originatingWorkspace = current_workspace(); 858*a10cf76eSAxel Dörfler 859*a10cf76eSAxel Dörfler // well, this "cannot be reverted" message is not 860*a10cf76eSAxel Dörfler // entirely true - at least, you can revert it 861*a10cf76eSAxel Dörfler // for current workspace; to not overwrite original 862*a10cf76eSAxel Dörfler // mode during workspace switch, we use this flag 863*a10cf76eSAxel Dörfler fChangingAllWorkspaces = true; 864*a10cf76eSAxel Dörfler 865*a10cf76eSAxel Dörfler for (int32 i = 0; i < count_workspaces(); i++) { 866*a10cf76eSAxel Dörfler if (i != originatingWorkspace) 867*a10cf76eSAxel Dörfler screen.SetMode(i, &newMode, true); 868*a10cf76eSAxel Dörfler } 869*a10cf76eSAxel Dörfler 870*a10cf76eSAxel Dörfler fChangingAllWorkspaces = false; 871*a10cf76eSAxel Dörfler } 872*a10cf76eSAxel Dörfler 873*a10cf76eSAxel Dörfler UpdateActiveMode(); 874*a10cf76eSAxel Dörfler break; 875*a10cf76eSAxel Dörfler } 876*a10cf76eSAxel Dörfler 877*a10cf76eSAxel Dörfler default: 878*a10cf76eSAxel Dörfler BWindow::MessageReceived(message); 879*a10cf76eSAxel Dörfler break; 880*a10cf76eSAxel Dörfler } 881*a10cf76eSAxel Dörfler } 882*a10cf76eSAxel Dörfler 883*a10cf76eSAxel Dörfler 884*a10cf76eSAxel Dörfler bool 885*a10cf76eSAxel Dörfler ScreenWindow::CanApply() const 886*a10cf76eSAxel Dörfler { 887*a10cf76eSAxel Dörfler if (fAllWorkspacesItem->IsMarked()) 888*a10cf76eSAxel Dörfler return true; 889*a10cf76eSAxel Dörfler 890*a10cf76eSAxel Dörfler return fSelected != fActive; 891*a10cf76eSAxel Dörfler } 892*a10cf76eSAxel Dörfler 893*a10cf76eSAxel Dörfler 894*a10cf76eSAxel Dörfler bool 895*a10cf76eSAxel Dörfler ScreenWindow::CanRevert() const 896*a10cf76eSAxel Dörfler { 897*a10cf76eSAxel Dörfler if (fActive != fOriginal) 898*a10cf76eSAxel Dörfler return true; 899*a10cf76eSAxel Dörfler 900*a10cf76eSAxel Dörfler return CanApply(); 901*a10cf76eSAxel Dörfler } 902*a10cf76eSAxel Dörfler 903*a10cf76eSAxel Dörfler 904*a10cf76eSAxel Dörfler void 905*a10cf76eSAxel Dörfler ScreenWindow::CheckApplyEnabled() 906*a10cf76eSAxel Dörfler { 907*a10cf76eSAxel Dörfler fApplyButton->SetEnabled(CanApply()); 908*a10cf76eSAxel Dörfler fRevertButton->SetEnabled(CanRevert()); 909*a10cf76eSAxel Dörfler } 910*a10cf76eSAxel Dörfler 911*a10cf76eSAxel Dörfler 912*a10cf76eSAxel Dörfler void 913*a10cf76eSAxel Dörfler ScreenWindow::Apply() 914*a10cf76eSAxel Dörfler { 915*a10cf76eSAxel Dörfler if (fAllWorkspacesItem->IsMarked()) { 916*a10cf76eSAxel Dörfler BAlert *workspacesAlert = new BAlert("WorkspacesAlert", 917*a10cf76eSAxel Dörfler "Change all workspaces? This action cannot be reverted.", "Okay", "Cancel", 918*a10cf76eSAxel Dörfler NULL, B_WIDTH_AS_USUAL, B_WARNING_ALERT); 919*a10cf76eSAxel Dörfler 920*a10cf76eSAxel Dörfler if (workspacesAlert->Go() == 1) 921*a10cf76eSAxel Dörfler return; 922*a10cf76eSAxel Dörfler } 923*a10cf76eSAxel Dörfler 924*a10cf76eSAxel Dörfler if (fScreenMode.Set(fSelected) == B_OK) 925*a10cf76eSAxel Dörfler fActive = fSelected; 926*a10cf76eSAxel Dörfler 927*a10cf76eSAxel Dörfler // ToDo: only show alert when this is an unknown mode 928*a10cf76eSAxel Dörfler BWindow *window = new AlertWindow(this); 929*a10cf76eSAxel Dörfler window->Show(); 930*a10cf76eSAxel Dörfler } 931