1a10cf76eSAxel Dörfler /* 212580984SAxel Dörfler * Copyright 2001-2007, 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> 12a10cf76eSAxel Dörfler */ 13a10cf76eSAxel Dörfler 14a10cf76eSAxel Dörfler 15a10cf76eSAxel Dörfler #include "AlertWindow.h" 16a10cf76eSAxel Dörfler #include "Constants.h" 17a10cf76eSAxel Dörfler #include "RefreshWindow.h" 18a10cf76eSAxel Dörfler #include "MonitorView.h" 19a10cf76eSAxel Dörfler #include "ScreenSettings.h" 20a10cf76eSAxel Dörfler #include "ScreenWindow.h" 21a10cf76eSAxel Dörfler #include "Utility.h" 22a10cf76eSAxel Dörfler 23a10cf76eSAxel Dörfler /* Note, this headers defines a *private* interface to the Radeon accelerant. 24a10cf76eSAxel Dörfler * It's a solution that works with the current BeOS interface that Haiku 25a10cf76eSAxel Dörfler * adopted. 26a10cf76eSAxel Dörfler * However, it's not a nice and clean solution. Don't use this header in any 27a10cf76eSAxel Dörfler * application if you can avoid it. No other driver is using this, or should 28a10cf76eSAxel Dörfler * be using this. 29a10cf76eSAxel Dörfler * It will be replaced as soon as we introduce an updated accelerant interface 30a10cf76eSAxel Dörfler * which may even happen before R1 hits the streets. 31a10cf76eSAxel Dörfler */ 32a10cf76eSAxel Dörfler #include "multimon.h" // the usual: DANGER WILL, ROBINSON! 33a10cf76eSAxel Dörfler 3412580984SAxel Dörfler #include <Alert.h> 3512580984SAxel Dörfler #include <Application.h> 3612580984SAxel Dörfler #include <Box.h> 3712580984SAxel Dörfler #include <Button.h> 3812580984SAxel Dörfler #include <Directory.h> 3912580984SAxel Dörfler #include <File.h> 4012580984SAxel Dörfler #include <FindDirectory.h> 4112580984SAxel Dörfler #include <InterfaceDefs.h> 4212580984SAxel Dörfler #include <MenuBar.h> 4312580984SAxel Dörfler #include <MenuItem.h> 4412580984SAxel Dörfler #include <MenuField.h> 4512580984SAxel Dörfler #include <Messenger.h> 4612580984SAxel Dörfler #include <Path.h> 4712580984SAxel Dörfler #include <PopUpMenu.h> 4812580984SAxel Dörfler #include <Screen.h> 4912580984SAxel Dörfler #include <String.h> 5012580984SAxel Dörfler #include <Roster.h> 5112580984SAxel Dörfler #include <Window.h> 5212580984SAxel Dörfler 5312580984SAxel Dörfler #include <stdio.h> 5412580984SAxel Dörfler #include <stdlib.h> 5512580984SAxel Dörfler #include <string.h> 5612580984SAxel Dörfler 57a10cf76eSAxel Dörfler 58c5d80d47SAxel Dörfler const char* kBackgroundsSignature = "application/x-vnd.haiku-backgrounds"; 59c5d80d47SAxel Dörfler 60a10cf76eSAxel Dörfler // list of officially supported colour spaces 61a10cf76eSAxel Dörfler static const struct { 62a10cf76eSAxel Dörfler color_space space; 63a10cf76eSAxel Dörfler int32 bits_per_pixel; 64a10cf76eSAxel Dörfler const char* label; 65a10cf76eSAxel Dörfler } kColorSpaces[] = { 66a10cf76eSAxel Dörfler { B_CMAP8, 8, "8 Bits/Pixel, 256 Colors" }, 67a10cf76eSAxel Dörfler { B_RGB15, 15, "15 Bits/Pixel, 32768 Colors" }, 68a10cf76eSAxel Dörfler { B_RGB16, 16, "16 Bits/Pixel, 65536 Colors" }, 69a10cf76eSAxel Dörfler { B_RGB32, 32, "32 Bits/Pixel, 16 Million Colors" } 70a10cf76eSAxel Dörfler }; 71a10cf76eSAxel Dörfler static const int32 kColorSpaceCount = sizeof(kColorSpaces) / sizeof(kColorSpaces[0]); 72a10cf76eSAxel Dörfler 73a10cf76eSAxel Dörfler // list of standard refresh rates 74a796facfSAxel Dörfler static const int32 kRefreshRates[] = { 60, 70, 72, 75, 80, 85, 95, 100 }; 75a10cf76eSAxel Dörfler static const int32 kRefreshRateCount = sizeof(kRefreshRates) / sizeof(kRefreshRates[0]); 76a10cf76eSAxel Dörfler 77a10cf76eSAxel Dörfler // list of combine modes 78a10cf76eSAxel Dörfler static const struct { 79a10cf76eSAxel Dörfler combine_mode mode; 80a10cf76eSAxel Dörfler const char *name; 81a10cf76eSAxel Dörfler } kCombineModes[] = { 82a10cf76eSAxel Dörfler { kCombineDisable, "disable" }, 83a10cf76eSAxel Dörfler { kCombineHorizontally, "horizontally" }, 84a10cf76eSAxel Dörfler { kCombineVertically, "vertically" } 85a10cf76eSAxel Dörfler }; 86a10cf76eSAxel Dörfler static const int32 kCombineModeCount = sizeof(kCombineModes) / sizeof(kCombineModes[0]); 87a10cf76eSAxel Dörfler 8829e8a73aSAxel Dörfler enum { 8929e8a73aSAxel Dörfler SHOW_COMBINE_FIELD = 0x01, 9029e8a73aSAxel Dörfler SHOW_SWAP_FIELD = 0x02, 9129e8a73aSAxel Dörfler SHOW_LAPTOP_PANEL_FIELD = 0x04, 9229e8a73aSAxel Dörfler SHOW_TV_STANDARD_FIELD = 0x08, 9329e8a73aSAxel Dörfler }; 9429e8a73aSAxel Dörfler 95a10cf76eSAxel Dörfler 96a10cf76eSAxel Dörfler static BString 97a10cf76eSAxel Dörfler tv_standard_to_string(uint32 mode) 98a10cf76eSAxel Dörfler { 99a10cf76eSAxel Dörfler switch (mode) { 100a10cf76eSAxel Dörfler case 0: return "disabled"; 101a10cf76eSAxel Dörfler case 1: return "NTSC"; 102a10cf76eSAxel Dörfler case 2: return "NTSC Japan"; 103a10cf76eSAxel Dörfler case 3: return "PAL BDGHI"; 104a10cf76eSAxel Dörfler case 4: return "PAL M"; 105a10cf76eSAxel Dörfler case 5: return "PAL N"; 106a10cf76eSAxel Dörfler case 6: return "SECAM"; 107a10cf76eSAxel Dörfler case 101: return "NTSC 443"; 108a10cf76eSAxel Dörfler case 102: return "PAL 60"; 109a10cf76eSAxel Dörfler case 103: return "PAL NC"; 110a10cf76eSAxel Dörfler default: 111a10cf76eSAxel Dörfler { 112a10cf76eSAxel Dörfler BString name; 113a10cf76eSAxel Dörfler name << "??? (" << mode << ")"; 114a10cf76eSAxel Dörfler 115a10cf76eSAxel Dörfler return name; 116a10cf76eSAxel Dörfler } 117a10cf76eSAxel Dörfler } 118a10cf76eSAxel Dörfler } 119a10cf76eSAxel Dörfler 120a10cf76eSAxel Dörfler 121a10cf76eSAxel Dörfler static void 122a10cf76eSAxel Dörfler resolution_to_string(screen_mode& mode, BString &string) 123a10cf76eSAxel Dörfler { 124a10cf76eSAxel Dörfler string << mode.width << " x " << mode.height; 125a10cf76eSAxel Dörfler } 126a10cf76eSAxel Dörfler 127a10cf76eSAxel Dörfler 128a10cf76eSAxel Dörfler static void 129a10cf76eSAxel Dörfler refresh_rate_to_string(float refresh, BString &string, 130a10cf76eSAxel Dörfler bool appendUnit = true, bool alwaysWithFraction = false) 131a10cf76eSAxel Dörfler { 132a10cf76eSAxel Dörfler snprintf(string.LockBuffer(32), 32, "%.*g", refresh >= 100.0 ? 4 : 3, refresh); 133a10cf76eSAxel Dörfler string.UnlockBuffer(); 134a10cf76eSAxel Dörfler 135a10cf76eSAxel Dörfler if (appendUnit) 136a10cf76eSAxel Dörfler string << " Hz"; 137a10cf76eSAxel Dörfler } 138a10cf76eSAxel Dörfler 139a10cf76eSAxel Dörfler 14007184a9eSAxel Dörfler static const char* 14107184a9eSAxel Dörfler screen_errors(status_t status) 14207184a9eSAxel Dörfler { 14307184a9eSAxel Dörfler switch (status) { 14407184a9eSAxel Dörfler case B_ENTRY_NOT_FOUND: 14507184a9eSAxel Dörfler return "Unknown Mode"; 14607184a9eSAxel Dörfler // TODO: add more? 14707184a9eSAxel Dörfler 14807184a9eSAxel Dörfler default: 14907184a9eSAxel Dörfler return strerror(status); 15007184a9eSAxel Dörfler } 15107184a9eSAxel Dörfler } 15207184a9eSAxel Dörfler 15329e8a73aSAxel Dörfler 15429e8a73aSAxel Dörfler static float 15529e8a73aSAxel Dörfler max_label_width(BMenuField* control, float widestLabel) 15629e8a73aSAxel Dörfler { 15729e8a73aSAxel Dörfler float labelWidth = control->StringWidth(control->Label()); 15829e8a73aSAxel Dörfler if (widestLabel < labelWidth) 15929e8a73aSAxel Dörfler return labelWidth; 16029e8a73aSAxel Dörfler return widestLabel; 16129e8a73aSAxel Dörfler } 16229e8a73aSAxel Dörfler 16329e8a73aSAxel Dörfler 16429e8a73aSAxel Dörfler static BRect 16529e8a73aSAxel Dörfler stack_and_align_menu_fields(const BList& menuFields) 16629e8a73aSAxel Dörfler { 16729e8a73aSAxel Dörfler float widestLabel = 0.0; 16829e8a73aSAxel Dörfler int32 count = menuFields.CountItems(); 16929e8a73aSAxel Dörfler for (int32 i = 0; i < count; i++) { 17029e8a73aSAxel Dörfler BMenuField* menuField = (BMenuField*)menuFields.ItemAtFast(i); 17129e8a73aSAxel Dörfler widestLabel = max_label_width(menuField, widestLabel); 17229e8a73aSAxel Dörfler } 17329e8a73aSAxel Dörfler 17429e8a73aSAxel Dörfler // add some room (but only if there is text at all) 17529e8a73aSAxel Dörfler if (widestLabel > 0.0) 17629e8a73aSAxel Dörfler widestLabel += 5.0; 17729e8a73aSAxel Dörfler 17829e8a73aSAxel Dörfler // make all controls the same width 179*d1516993SAxel Dörfler float widestField = 0.0f; 18029e8a73aSAxel Dörfler for (int32 i = 0; i < count; i++) { 18129e8a73aSAxel Dörfler BMenuField* menuField = (BMenuField*)menuFields.ItemAtFast(i); 182*d1516993SAxel Dörfler if (widestField == 0.0f) { 183*d1516993SAxel Dörfler widestField = menuField->StringWidth("9999 x 9999 WWW") 184*d1516993SAxel Dörfler + widestLabel; 185*d1516993SAxel Dörfler } 18629e8a73aSAxel Dörfler menuField->SetAlignment(B_ALIGN_RIGHT); 18729e8a73aSAxel Dörfler menuField->SetDivider(widestLabel); 18829e8a73aSAxel Dörfler menuField->ResizeToPreferred(); 18929e8a73aSAxel Dörfler widestField = max_c(menuField->Bounds().Width(), widestField); 19029e8a73aSAxel Dörfler } 19129e8a73aSAxel Dörfler 19229e8a73aSAxel Dörfler // layout controls under each other, resize all to size 19329e8a73aSAxel Dörfler // of largest of them (they could still have different 19429e8a73aSAxel Dörfler // heights though) 19529e8a73aSAxel Dörfler BMenuField* topMenuField = (BMenuField*)menuFields.FirstItem(); 19629e8a73aSAxel Dörfler BPoint leftTop = topMenuField->Frame().LeftTop(); 19729e8a73aSAxel Dörfler BRect frame = topMenuField->Frame(); 19829e8a73aSAxel Dörfler 19929e8a73aSAxel Dörfler for (int32 i = 0; i < count; i++) { 20029e8a73aSAxel Dörfler BMenuField* menuField = (BMenuField*)menuFields.ItemAtFast(i); 20129e8a73aSAxel Dörfler menuField->MoveTo(leftTop); 20229e8a73aSAxel Dörfler float height = menuField->Bounds().Height(); 20329e8a73aSAxel Dörfler menuField->ResizeTo(widestField, height); 20429e8a73aSAxel Dörfler frame = frame | menuField->Frame(); 20529e8a73aSAxel Dörfler leftTop.y += height + 5.0; 20629e8a73aSAxel Dörfler } 20729e8a73aSAxel Dörfler 20829e8a73aSAxel Dörfler return frame; 20929e8a73aSAxel Dörfler } 210df3f5bacSStephan Aßmus 211df3f5bacSStephan Aßmus 2123dfd20c0SStephan Aßmus // #pragma mark - 2133dfd20c0SStephan Aßmus 2143dfd20c0SStephan Aßmus 2155a78744bSAxel Dörfler ScreenWindow::ScreenWindow(ScreenSettings *settings) 2165a78744bSAxel Dörfler : BWindow(settings->WindowFrame(), "Screen", B_TITLED_WINDOW, 217a10cf76eSAxel Dörfler B_NOT_RESIZABLE | B_NOT_ZOOMABLE, B_ALL_WORKSPACES), 21812580984SAxel Dörfler fIsVesa(false), 21912580984SAxel Dörfler fVesaApplied(false), 220a10cf76eSAxel Dörfler fScreenMode(this), 221abc649b8SWaldemar Kornewald fTempScreenMode(this), 222abc649b8SWaldemar Kornewald fModified(false) 223a10cf76eSAxel Dörfler { 224a10cf76eSAxel Dörfler BScreen screen(this); 225a10cf76eSAxel Dörfler 22612580984SAxel Dörfler accelerant_device_info info; 227*d1516993SAxel Dörfler if (screen.GetDeviceInfo(&info) == B_OK 228*d1516993SAxel Dörfler && !strcasecmp(info.chipset, "VESA")) 22912580984SAxel Dörfler fIsVesa = true; 23012580984SAxel Dörfler 231abc649b8SWaldemar Kornewald UpdateOriginal(); 232a10cf76eSAxel Dörfler fActive = fSelected = fOriginal; 233a10cf76eSAxel Dörfler 234df3f5bacSStephan Aßmus BView *view = new BView(Bounds(), "ScreenView", B_FOLLOW_ALL, B_WILL_DRAW); 235a10cf76eSAxel Dörfler view->SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR)); 236a10cf76eSAxel Dörfler AddChild(view); 237a10cf76eSAxel Dörfler 2385a78744bSAxel Dörfler fSettings = settings; 2395a78744bSAxel Dörfler 2405a78744bSAxel Dörfler // we need the "Current Workspace" first to get its height 2415a78744bSAxel Dörfler 2425a78744bSAxel Dörfler BPopUpMenu *popUpMenu = new BPopUpMenu("Current Workspace", true, true); 243*d1516993SAxel Dörfler fAllWorkspacesItem = new BMenuItem("All Workspaces", 244*d1516993SAxel Dörfler new BMessage(WORKSPACE_CHECK_MSG)); 2455a78744bSAxel Dörfler popUpMenu->AddItem(fAllWorkspacesItem); 246*d1516993SAxel Dörfler BMenuItem *item = new BMenuItem("Current Workspace", 247*d1516993SAxel Dörfler new BMessage(WORKSPACE_CHECK_MSG)); 24812580984SAxel Dörfler if (_IsVesa()) { 24912580984SAxel Dörfler fAllWorkspacesItem->SetMarked(true); 25012580984SAxel Dörfler item->SetEnabled(false); 25112580984SAxel Dörfler } else 2525a78744bSAxel Dörfler item->SetMarked(true); 2535a78744bSAxel Dörfler popUpMenu->AddItem(item); 2545a78744bSAxel Dörfler 255df3f5bacSStephan Aßmus BMenuField* workspaceMenuField = new BMenuField(BRect(0, 0, 100, 15), 2565a78744bSAxel Dörfler "WorkspaceMenu", NULL, popUpMenu, true); 2575a78744bSAxel Dörfler workspaceMenuField->ResizeToPreferred(); 258a10cf76eSAxel Dörfler 259a10cf76eSAxel Dörfler // box on the left with workspace count and monitor view 260a10cf76eSAxel Dörfler 2615a78744bSAxel Dörfler popUpMenu = new BPopUpMenu("", true, true); 262df3f5bacSStephan Aßmus fWorkspaceCountField = new BMenuField(BRect(0.0, 0.0, 50.0, 15.0), 263df3f5bacSStephan Aßmus "WorkspaceCountMenu", "Workspace count:", popUpMenu, true); 264*d1516993SAxel Dörfler float labelWidth = fWorkspaceCountField->StringWidth( 265*d1516993SAxel Dörfler fWorkspaceCountField->Label()) + 5.0; 266df3f5bacSStephan Aßmus fWorkspaceCountField->SetDivider(labelWidth); 267df3f5bacSStephan Aßmus 268df3f5bacSStephan Aßmus fScreenBox = new BBox(BRect(0.0, 0.0, 100.0, 100.0), "left box"); 269df3f5bacSStephan Aßmus fScreenBox->AddChild(fWorkspaceCountField); 270a10cf76eSAxel Dörfler 271a10cf76eSAxel Dörfler for (int32 count = 1; count <= 32; count++) { 272a10cf76eSAxel Dörfler BString workspaceCount; 273a10cf76eSAxel Dörfler workspaceCount << count; 274a10cf76eSAxel Dörfler 275a10cf76eSAxel Dörfler BMessage *message = new BMessage(POP_WORKSPACE_CHANGED_MSG); 276a10cf76eSAxel Dörfler message->AddInt32("workspace count", count); 277a10cf76eSAxel Dörfler 278a10cf76eSAxel Dörfler popUpMenu->AddItem(new BMenuItem(workspaceCount.String(), 279a10cf76eSAxel Dörfler message)); 280a10cf76eSAxel Dörfler } 281a10cf76eSAxel Dörfler 2825a78744bSAxel Dörfler item = popUpMenu->ItemAt(count_workspaces() - 1); 283a10cf76eSAxel Dörfler if (item != NULL) 284a10cf76eSAxel Dörfler item->SetMarked(true); 285a10cf76eSAxel Dörfler 286df3f5bacSStephan Aßmus fMonitorView = new MonitorView(BRect(0.0, 0.0, 80.0, 80.0), "monitor", 2875a78744bSAxel Dörfler screen.Frame().Width() + 1, screen.Frame().Height() + 1); 288df3f5bacSStephan Aßmus fScreenBox->AddChild(fMonitorView); 2895a78744bSAxel Dörfler 290df3f5bacSStephan Aßmus view->AddChild(fScreenBox); 291a10cf76eSAxel Dörfler 292a10cf76eSAxel Dörfler // box on the right with screen resolution, etc. 293a10cf76eSAxel Dörfler 294df3f5bacSStephan Aßmus fControlsBox = new BBox(BRect(0.0, 0.0, 100.0, 100.0)); 295df3f5bacSStephan Aßmus fControlsBox->SetLabel(workspaceMenuField); 296a10cf76eSAxel Dörfler 297a10cf76eSAxel Dörfler fResolutionMenu = new BPopUpMenu("resolution", true, true); 298a10cf76eSAxel Dörfler 299a10cf76eSAxel Dörfler uint16 previousWidth = 0, previousHeight = 0; 300a10cf76eSAxel Dörfler for (int32 i = 0; i < fScreenMode.CountModes(); i++) { 301a10cf76eSAxel Dörfler screen_mode mode = fScreenMode.ModeAt(i); 302a10cf76eSAxel Dörfler 303a10cf76eSAxel Dörfler if (mode.width == previousWidth && mode.height == previousHeight) 304a10cf76eSAxel Dörfler continue; 305a10cf76eSAxel Dörfler 306a10cf76eSAxel Dörfler previousWidth = mode.width; 307a10cf76eSAxel Dörfler previousHeight = mode.height; 308a10cf76eSAxel Dörfler 309a10cf76eSAxel Dörfler BMessage *message = new BMessage(POP_RESOLUTION_MSG); 310a10cf76eSAxel Dörfler message->AddInt32("width", mode.width); 311a10cf76eSAxel Dörfler message->AddInt32("height", mode.height); 312a10cf76eSAxel Dörfler 313a10cf76eSAxel Dörfler BString name; 314a10cf76eSAxel Dörfler name << mode.width << " x " << mode.height; 315a10cf76eSAxel Dörfler 316a10cf76eSAxel Dörfler fResolutionMenu->AddItem(new BMenuItem(name.String(), message)); 317a10cf76eSAxel Dörfler } 318a10cf76eSAxel Dörfler 31929e8a73aSAxel Dörfler BRect rect(0.0, 0.0, 200.0, 15.0); 320df3f5bacSStephan Aßmus // fResolutionField needs to be at the correct 321df3f5bacSStephan Aßmus // left-top offset, because all other menu fields 322df3f5bacSStephan Aßmus // will be layouted relative to it 323df3f5bacSStephan Aßmus fResolutionField = new BMenuField(rect.OffsetToCopy(10.0, 30.0), 324*d1516993SAxel Dörfler "ResolutionMenu", "Resolution:", fResolutionMenu, false); 325df3f5bacSStephan Aßmus fControlsBox->AddChild(fResolutionField); 326a10cf76eSAxel Dörfler 327a10cf76eSAxel Dörfler fColorsMenu = new BPopUpMenu("colors", true, true); 328a10cf76eSAxel Dörfler 329a10cf76eSAxel Dörfler for (int32 i = 0; i < kColorSpaceCount; i++) { 330a10cf76eSAxel Dörfler BMessage *message = new BMessage(POP_COLORS_MSG); 331a10cf76eSAxel Dörfler message->AddInt32("bits_per_pixel", kColorSpaces[i].bits_per_pixel); 332a10cf76eSAxel Dörfler message->AddInt32("space", kColorSpaces[i].space); 333a10cf76eSAxel Dörfler 334a10cf76eSAxel Dörfler fColorsMenu->AddItem(new BMenuItem(kColorSpaces[i].label, message)); 335a10cf76eSAxel Dörfler } 336a10cf76eSAxel Dörfler 337df3f5bacSStephan Aßmus rect.OffsetTo(B_ORIGIN); 338df3f5bacSStephan Aßmus 339*d1516993SAxel Dörfler fColorsField = new BMenuField(rect, "ColorsMenu", "Colors:", fColorsMenu, 340*d1516993SAxel Dörfler false); 341df3f5bacSStephan Aßmus fControlsBox->AddChild(fColorsField); 342a10cf76eSAxel Dörfler 343a10cf76eSAxel Dörfler fRefreshMenu = new BPopUpMenu("refresh rate", true, true); 344a10cf76eSAxel Dörfler 34529e8a73aSAxel Dörfler BMessage *message; 34629e8a73aSAxel Dörfler 34729e8a73aSAxel Dörfler float min, max; 34829e8a73aSAxel Dörfler if (fScreenMode.GetRefreshLimits(fActive, min, max) && min == max) { 34929e8a73aSAxel Dörfler // This is a special case for drivers that only support a single 35029e8a73aSAxel Dörfler // frequency, like the VESA driver 35129e8a73aSAxel Dörfler BString name; 35229e8a73aSAxel Dörfler name << min << " Hz"; 35329e8a73aSAxel Dörfler 35429e8a73aSAxel Dörfler message = new BMessage(POP_REFRESH_MSG); 35529e8a73aSAxel Dörfler message->AddFloat("refresh", min); 35629e8a73aSAxel Dörfler 35729e8a73aSAxel Dörfler fRefreshMenu->AddItem(item = new BMenuItem(name.String(), message)); 35829e8a73aSAxel Dörfler item->SetEnabled(false); 35929e8a73aSAxel Dörfler } else { 360a10cf76eSAxel Dörfler for (int32 i = 0; i < kRefreshRateCount; ++i) { 361a10cf76eSAxel Dörfler BString name; 362a10cf76eSAxel Dörfler name << kRefreshRates[i] << " Hz"; 363a10cf76eSAxel Dörfler 36429e8a73aSAxel Dörfler message = new BMessage(POP_REFRESH_MSG); 365a10cf76eSAxel Dörfler message->AddFloat("refresh", kRefreshRates[i]); 366a10cf76eSAxel Dörfler 367a10cf76eSAxel Dörfler fRefreshMenu->AddItem(new BMenuItem(name.String(), message)); 368a10cf76eSAxel Dörfler } 369a10cf76eSAxel Dörfler 37029e8a73aSAxel Dörfler message = new BMessage(POP_OTHER_REFRESH_MSG); 371a10cf76eSAxel Dörfler 372a10cf76eSAxel Dörfler fOtherRefresh = new BMenuItem("Other" B_UTF8_ELLIPSIS, message); 373a10cf76eSAxel Dörfler fRefreshMenu->AddItem(fOtherRefresh); 37429e8a73aSAxel Dörfler } 375a10cf76eSAxel Dörfler 376*d1516993SAxel Dörfler fRefreshField = new BMenuField(rect, "RefreshMenu", "Refresh Rate:", 377*d1516993SAxel Dörfler fRefreshMenu, false); 37812580984SAxel Dörfler if (_IsVesa()) 37912580984SAxel Dörfler fRefreshField->Hide(); 380df3f5bacSStephan Aßmus fControlsBox->AddChild(fRefreshField); 381a10cf76eSAxel Dörfler 382df3f5bacSStephan Aßmus view->AddChild(fControlsBox); 383df3f5bacSStephan Aßmus 384df3f5bacSStephan Aßmus uint32 controlsFlags = 0; 385a10cf76eSAxel Dörfler 386a10cf76eSAxel Dörfler // enlarged area for multi-monitor settings 387a10cf76eSAxel Dörfler { 388a10cf76eSAxel Dörfler bool dummy; 389a10cf76eSAxel Dörfler uint32 dummy32; 390a10cf76eSAxel Dörfler bool multiMonSupport; 391a10cf76eSAxel Dörfler bool useLaptopPanelSupport; 392a10cf76eSAxel Dörfler bool tvStandardSupport; 393a10cf76eSAxel Dörfler 394a10cf76eSAxel Dörfler multiMonSupport = TestMultiMonSupport(&screen) == B_OK; 395a10cf76eSAxel Dörfler useLaptopPanelSupport = GetUseLaptopPanel(&screen, &dummy) == B_OK; 396a10cf76eSAxel Dörfler tvStandardSupport = GetTVStandard(&screen, &dummy32) == B_OK; 397df3f5bacSStephan Aßmus if (multiMonSupport) { 398df3f5bacSStephan Aßmus controlsFlags |= SHOW_COMBINE_FIELD; 399df3f5bacSStephan Aßmus controlsFlags |= SHOW_SWAP_FIELD; 400df3f5bacSStephan Aßmus } 401df3f5bacSStephan Aßmus if (useLaptopPanelSupport) 402df3f5bacSStephan Aßmus controlsFlags |= SHOW_LAPTOP_PANEL_FIELD; 403a10cf76eSAxel Dörfler 404a10cf76eSAxel Dörfler // even if there is no support, we still create all controls 405a10cf76eSAxel Dörfler // to make sure we don't access NULL pointers later on 406a10cf76eSAxel Dörfler 407a10cf76eSAxel Dörfler fCombineMenu = new BPopUpMenu("CombineDisplays", true, true); 408a10cf76eSAxel Dörfler 409a10cf76eSAxel Dörfler for (int32 i = 0; i < kCombineModeCount; i++) { 410a10cf76eSAxel Dörfler message = new BMessage(POP_COMBINE_DISPLAYS_MSG); 411a10cf76eSAxel Dörfler message->AddInt32("mode", kCombineModes[i].mode); 412a10cf76eSAxel Dörfler 413*d1516993SAxel Dörfler fCombineMenu->AddItem(new BMenuItem(kCombineModes[i].name, 414*d1516993SAxel Dörfler message)); 415a10cf76eSAxel Dörfler } 416a10cf76eSAxel Dörfler 417df3f5bacSStephan Aßmus fCombineField = new BMenuField(rect, "CombineMenu", 418*d1516993SAxel Dörfler "Combine Displays:", fCombineMenu, false); 419df3f5bacSStephan Aßmus fControlsBox->AddChild(fCombineField); 420a10cf76eSAxel Dörfler 421a10cf76eSAxel Dörfler if (!multiMonSupport) 422df3f5bacSStephan Aßmus fCombineField->Hide(); 423a10cf76eSAxel Dörfler 424a10cf76eSAxel Dörfler fSwapDisplaysMenu = new BPopUpMenu("SwapDisplays", true, true); 425a10cf76eSAxel Dörfler 426a10cf76eSAxel Dörfler // !order is important - we rely that boolean value == idx 427a10cf76eSAxel Dörfler message = new BMessage(POP_SWAP_DISPLAYS_MSG); 428a10cf76eSAxel Dörfler message->AddBool("swap", false); 429a10cf76eSAxel Dörfler fSwapDisplaysMenu->AddItem(new BMenuItem("no", message)); 430a10cf76eSAxel Dörfler 431a10cf76eSAxel Dörfler message = new BMessage(POP_SWAP_DISPLAYS_MSG); 432a10cf76eSAxel Dörfler message->AddBool("swap", true); 433a10cf76eSAxel Dörfler fSwapDisplaysMenu->AddItem(new BMenuItem("yes", message)); 434a10cf76eSAxel Dörfler 435df3f5bacSStephan Aßmus fSwapDisplaysField = new BMenuField(rect, "SwapMenu", "Swap Displays:", 436*d1516993SAxel Dörfler fSwapDisplaysMenu, false); 437a10cf76eSAxel Dörfler 438df3f5bacSStephan Aßmus fControlsBox->AddChild(fSwapDisplaysField); 439a10cf76eSAxel Dörfler if (!multiMonSupport) 440df3f5bacSStephan Aßmus fSwapDisplaysField->Hide(); 441a10cf76eSAxel Dörfler 442a10cf76eSAxel Dörfler fUseLaptopPanelMenu = new BPopUpMenu("UseLaptopPanel", true, true); 443a10cf76eSAxel Dörfler 444a10cf76eSAxel Dörfler // !order is important - we rely that boolean value == idx 445a10cf76eSAxel Dörfler message = new BMessage(POP_USE_LAPTOP_PANEL_MSG); 446a10cf76eSAxel Dörfler message->AddBool("use", false); 447a10cf76eSAxel Dörfler fUseLaptopPanelMenu->AddItem(new BMenuItem("if needed", message)); 448a10cf76eSAxel Dörfler 449a10cf76eSAxel Dörfler message = new BMessage(POP_USE_LAPTOP_PANEL_MSG); 450a10cf76eSAxel Dörfler message->AddBool("use", true); 451a10cf76eSAxel Dörfler fUseLaptopPanelMenu->AddItem(new BMenuItem("always", message)); 452a10cf76eSAxel Dörfler 453*d1516993SAxel Dörfler fUseLaptopPanelField = new BMenuField(rect, "UseLaptopPanel", 454*d1516993SAxel Dörfler "Use Laptop Panel:", fUseLaptopPanelMenu, false); 455a10cf76eSAxel Dörfler 456df3f5bacSStephan Aßmus fControlsBox->AddChild(fUseLaptopPanelField); 457a10cf76eSAxel Dörfler if (!useLaptopPanelSupport) 458df3f5bacSStephan Aßmus fUseLaptopPanelField->Hide(); 459a10cf76eSAxel Dörfler 460a10cf76eSAxel Dörfler fTVStandardMenu = new BPopUpMenu("TVStandard", true, true); 461a10cf76eSAxel Dörfler 462a10cf76eSAxel Dörfler // arbitrary limit 463a10cf76eSAxel Dörfler uint32 i; 464a10cf76eSAxel Dörfler for (i = 0; i < 100; ++i) { 465a10cf76eSAxel Dörfler uint32 mode; 466a10cf76eSAxel Dörfler if (GetNthSupportedTVStandard(&screen, i, &mode) != B_OK) 467a10cf76eSAxel Dörfler break; 468a10cf76eSAxel Dörfler 469a10cf76eSAxel Dörfler BString name = tv_standard_to_string(mode); 470a10cf76eSAxel Dörfler 471a10cf76eSAxel Dörfler message = new BMessage(POP_TV_STANDARD_MSG); 472a10cf76eSAxel Dörfler message->AddInt32("tv_standard", mode); 473a10cf76eSAxel Dörfler 474a10cf76eSAxel Dörfler fTVStandardMenu->AddItem(new BMenuItem(name.String(), message)); 475a10cf76eSAxel Dörfler } 476a10cf76eSAxel Dörfler 477df3f5bacSStephan Aßmus fTVStandardField = new BMenuField(rect, "tv standard", "Video Format:", 478*d1516993SAxel Dörfler fTVStandardMenu, false); 479df3f5bacSStephan Aßmus fTVStandardField->SetAlignment(B_ALIGN_RIGHT); 480a10cf76eSAxel Dörfler 481df3f5bacSStephan Aßmus if (!tvStandardSupport || i == 0) { 482df3f5bacSStephan Aßmus fTVStandardField->Hide(); 483df3f5bacSStephan Aßmus } else { 484df3f5bacSStephan Aßmus controlsFlags |= SHOW_TV_STANDARD_FIELD; 485a10cf76eSAxel Dörfler } 486a10cf76eSAxel Dörfler 487df3f5bacSStephan Aßmus fControlsBox->AddChild(fTVStandardField); 488df3f5bacSStephan Aßmus } 489df3f5bacSStephan Aßmus 490df3f5bacSStephan Aßmus BRect buttonRect(0.0, 0.0, 30.0, 10.0); 491df3f5bacSStephan Aßmus fBackgroundsButton = new BButton(buttonRect, "BackgroundsButton", 492*d1516993SAxel Dörfler "Set Background"B_UTF8_ELLIPSIS, 493*d1516993SAxel Dörfler new BMessage(BUTTON_LAUNCH_BACKGROUNDS_MSG)); 4943dfd20c0SStephan Aßmus fBackgroundsButton->SetFontSize(be_plain_font->Size() * 0.9); 495df3f5bacSStephan Aßmus fScreenBox->AddChild(fBackgroundsButton); 496df3f5bacSStephan Aßmus 497abc649b8SWaldemar Kornewald // TODO: we don't support getting the screen's preferred settings 498abc649b8SWaldemar Kornewald /* fDefaultsButton = new BButton(buttonRect, "DefaultsButton", "Defaults", 499a10cf76eSAxel Dörfler new BMessage(BUTTON_DEFAULTS_MSG)); 500abc649b8SWaldemar Kornewald view->AddChild(fDefaultsButton); */ 501a10cf76eSAxel Dörfler 502df3f5bacSStephan Aßmus fRevertButton = new BButton(buttonRect, "RevertButton", "Revert", 503a10cf76eSAxel Dörfler new BMessage(BUTTON_REVERT_MSG)); 504a10cf76eSAxel Dörfler fRevertButton->SetEnabled(false); 505a10cf76eSAxel Dörfler view->AddChild(fRevertButton); 506a10cf76eSAxel Dörfler 507df3f5bacSStephan Aßmus fApplyButton = new BButton(buttonRect, "ApplyButton", "Apply", 508df3f5bacSStephan Aßmus new BMessage(BUTTON_APPLY_MSG)); 509df3f5bacSStephan Aßmus fApplyButton->SetEnabled(false); 510abc649b8SWaldemar Kornewald fControlsBox->AddChild(fApplyButton); 5115a78744bSAxel Dörfler 512a10cf76eSAxel Dörfler UpdateControls(); 513df3f5bacSStephan Aßmus 514df3f5bacSStephan Aßmus LayoutControls(controlsFlags); 515a10cf76eSAxel Dörfler } 516a10cf76eSAxel Dörfler 517a10cf76eSAxel Dörfler 518a10cf76eSAxel Dörfler ScreenWindow::~ScreenWindow() 519a10cf76eSAxel Dörfler { 520a10cf76eSAxel Dörfler delete fSettings; 521a10cf76eSAxel Dörfler } 522a10cf76eSAxel Dörfler 523a10cf76eSAxel Dörfler 524a10cf76eSAxel Dörfler bool 525a10cf76eSAxel Dörfler ScreenWindow::QuitRequested() 526a10cf76eSAxel Dörfler { 527a10cf76eSAxel Dörfler fSettings->SetWindowFrame(Frame()); 52812580984SAxel Dörfler if (fVesaApplied) { 52912580984SAxel Dörfler status_t status = _WriteVesaModeFile(fSelected); 53012580984SAxel Dörfler if (status < B_OK) { 53112580984SAxel Dörfler BString warning = "Could not write VESA mode settings file:\n\t"; 53212580984SAxel Dörfler warning << strerror(status); 53312580984SAxel Dörfler (new BAlert("VesaAlert", warning.String(), "Okay", NULL, NULL, 53412580984SAxel Dörfler B_WIDTH_AS_USUAL, B_WARNING_ALERT))->Go(); 53512580984SAxel Dörfler 53612580984SAxel Dörfler } 53712580984SAxel Dörfler } 53812580984SAxel Dörfler 539a10cf76eSAxel Dörfler be_app->PostMessage(B_QUIT_REQUESTED); 540a10cf76eSAxel Dörfler 541a10cf76eSAxel Dörfler return BWindow::QuitRequested(); 542a10cf76eSAxel Dörfler } 543a10cf76eSAxel Dörfler 544a10cf76eSAxel Dörfler 545a10cf76eSAxel Dörfler /** update resolution list according to combine mode 546a10cf76eSAxel Dörfler * (some resolution may not be combinable due to memory restrictions) 547a10cf76eSAxel Dörfler */ 548a10cf76eSAxel Dörfler 549a10cf76eSAxel Dörfler void 550a10cf76eSAxel Dörfler ScreenWindow::CheckResolutionMenu() 551a10cf76eSAxel Dörfler { 552a10cf76eSAxel Dörfler for (int32 i = 0; i < fResolutionMenu->CountItems(); i++) 553a10cf76eSAxel Dörfler fResolutionMenu->ItemAt(i)->SetEnabled(false); 554a10cf76eSAxel Dörfler 555a10cf76eSAxel Dörfler for (int32 i = 0; i < fScreenMode.CountModes(); i++) { 556a10cf76eSAxel Dörfler screen_mode mode = fScreenMode.ModeAt(i); 557a10cf76eSAxel Dörfler if (mode.combine != fSelected.combine) 558a10cf76eSAxel Dörfler continue; 559a10cf76eSAxel Dörfler 560a10cf76eSAxel Dörfler BString name; 561a10cf76eSAxel Dörfler name << mode.width << " x " << mode.height; 562a10cf76eSAxel Dörfler 563a10cf76eSAxel Dörfler BMenuItem *item = fResolutionMenu->FindItem(name.String()); 564a10cf76eSAxel Dörfler if (item != NULL) 565a10cf76eSAxel Dörfler item->SetEnabled(true); 566a10cf76eSAxel Dörfler } 567a10cf76eSAxel Dörfler } 568a10cf76eSAxel Dörfler 569a10cf76eSAxel Dörfler 570a10cf76eSAxel Dörfler /** update color and refresh options according to current mode 571a10cf76eSAxel Dörfler * (a color space is made active if there is any mode with 572a10cf76eSAxel Dörfler * given resolution and this colour space; same applies for 573a10cf76eSAxel Dörfler * refresh rate, though "Other…" is always possible) 574a10cf76eSAxel Dörfler */ 575a10cf76eSAxel Dörfler 576a10cf76eSAxel Dörfler void 577a10cf76eSAxel Dörfler ScreenWindow::CheckColorMenu() 578a10cf76eSAxel Dörfler { 579a10cf76eSAxel Dörfler for (int32 i = 0; i < kColorSpaceCount; i++) { 580a10cf76eSAxel Dörfler bool supported = false; 581a10cf76eSAxel Dörfler 582a10cf76eSAxel Dörfler for (int32 j = 0; j < fScreenMode.CountModes(); j++) { 583a10cf76eSAxel Dörfler screen_mode mode = fScreenMode.ModeAt(j); 584a10cf76eSAxel Dörfler 585a10cf76eSAxel Dörfler if (fSelected.width == mode.width 586a10cf76eSAxel Dörfler && fSelected.height == mode.height 587a10cf76eSAxel Dörfler && kColorSpaces[i].space == mode.space 588a10cf76eSAxel Dörfler && fSelected.combine == mode.combine) { 589a10cf76eSAxel Dörfler supported = true; 590a10cf76eSAxel Dörfler break; 591a10cf76eSAxel Dörfler } 592a10cf76eSAxel Dörfler } 593a10cf76eSAxel Dörfler 594a10cf76eSAxel Dörfler BMenuItem* item = fColorsMenu->ItemAt(i); 595a10cf76eSAxel Dörfler if (item) 596a10cf76eSAxel Dörfler item->SetEnabled(supported); 597a10cf76eSAxel Dörfler } 598a10cf76eSAxel Dörfler } 599a10cf76eSAxel Dörfler 600a10cf76eSAxel Dörfler 60129e8a73aSAxel Dörfler /** Enable/disable refresh options according to current mode. */ 602a10cf76eSAxel Dörfler 603a10cf76eSAxel Dörfler void 604a10cf76eSAxel Dörfler ScreenWindow::CheckRefreshMenu() 605a10cf76eSAxel Dörfler { 60629e8a73aSAxel Dörfler float min, max; 60729e8a73aSAxel Dörfler if (fScreenMode.GetRefreshLimits(fSelected, min, max) != B_OK || min == max) 60829e8a73aSAxel Dörfler return; 609a10cf76eSAxel Dörfler 61029e8a73aSAxel Dörfler for (int32 i = fRefreshMenu->CountItems(); i-- > 0;) { 61129e8a73aSAxel Dörfler BMenuItem* item = fRefreshMenu->ItemAt(i); 61229e8a73aSAxel Dörfler BMessage* message = item->Message(); 61329e8a73aSAxel Dörfler float refresh; 61429e8a73aSAxel Dörfler if (message != NULL && message->FindFloat("refresh", &refresh) == B_OK) 61529e8a73aSAxel Dörfler item->SetEnabled(refresh >= min && refresh <= max); 616a10cf76eSAxel Dörfler } 617a10cf76eSAxel Dörfler } 618a10cf76eSAxel Dörfler 619a10cf76eSAxel Dörfler 62029e8a73aSAxel Dörfler /** Activate appropriate menu item according to selected refresh rate */ 621a10cf76eSAxel Dörfler 622a10cf76eSAxel Dörfler void 623a10cf76eSAxel Dörfler ScreenWindow::UpdateRefreshControl() 624a10cf76eSAxel Dörfler { 625a10cf76eSAxel Dörfler BString string; 626a10cf76eSAxel Dörfler refresh_rate_to_string(fSelected.refresh, string); 627a10cf76eSAxel Dörfler 628a10cf76eSAxel Dörfler BMenuItem* item = fRefreshMenu->FindItem(string.String()); 629a10cf76eSAxel Dörfler if (item) { 630a10cf76eSAxel Dörfler if (!item->IsMarked()) 631a10cf76eSAxel Dörfler item->SetMarked(true); 63229e8a73aSAxel Dörfler 633a10cf76eSAxel Dörfler // "Other…" items only contains a refresh rate when active 634a10cf76eSAxel Dörfler fOtherRefresh->SetLabel("Other…"); 635a10cf76eSAxel Dörfler return; 636a10cf76eSAxel Dörfler } 637a10cf76eSAxel Dörfler 638a10cf76eSAxel Dörfler // this is a non-standard refresh rate 639a10cf76eSAxel Dörfler 640a10cf76eSAxel Dörfler fOtherRefresh->Message()->ReplaceFloat("refresh", fSelected.refresh); 641a10cf76eSAxel Dörfler fOtherRefresh->SetMarked(true); 642a10cf76eSAxel Dörfler 643a10cf76eSAxel Dörfler fRefreshMenu->Superitem()->SetLabel(string.String()); 644a10cf76eSAxel Dörfler 645a10cf76eSAxel Dörfler string.Append("/Other" B_UTF8_ELLIPSIS); 646a10cf76eSAxel Dörfler fOtherRefresh->SetLabel(string.String()); 647a10cf76eSAxel Dörfler } 648a10cf76eSAxel Dörfler 649a10cf76eSAxel Dörfler 650a10cf76eSAxel Dörfler void 651a10cf76eSAxel Dörfler ScreenWindow::UpdateMonitorView() 652a10cf76eSAxel Dörfler { 653a10cf76eSAxel Dörfler BMessage updateMessage(UPDATE_DESKTOP_MSG); 654a10cf76eSAxel Dörfler updateMessage.AddInt32("width", fSelected.width); 655a10cf76eSAxel Dörfler updateMessage.AddInt32("height", fSelected.height); 656a10cf76eSAxel Dörfler 657a10cf76eSAxel Dörfler PostMessage(&updateMessage, fMonitorView); 658a10cf76eSAxel Dörfler } 659a10cf76eSAxel Dörfler 660a10cf76eSAxel Dörfler 661a10cf76eSAxel Dörfler void 662a10cf76eSAxel Dörfler ScreenWindow::UpdateControls() 663a10cf76eSAxel Dörfler { 664a10cf76eSAxel Dörfler BMenuItem* item = fSwapDisplaysMenu->ItemAt((int32)fSelected.swap_displays); 665a10cf76eSAxel Dörfler if (item && !item->IsMarked()) 666a10cf76eSAxel Dörfler item->SetMarked(true); 667a10cf76eSAxel Dörfler 668a10cf76eSAxel Dörfler item = fUseLaptopPanelMenu->ItemAt((int32)fSelected.use_laptop_panel); 669a10cf76eSAxel Dörfler if (item && !item->IsMarked()) 670a10cf76eSAxel Dörfler item->SetMarked(true); 671a10cf76eSAxel Dörfler 672a10cf76eSAxel Dörfler for (int32 i = 0; i < fTVStandardMenu->CountItems(); i++) { 673a10cf76eSAxel Dörfler item = fTVStandardMenu->ItemAt(i); 674a10cf76eSAxel Dörfler 675a10cf76eSAxel Dörfler uint32 tvStandard; 676a10cf76eSAxel Dörfler item->Message()->FindInt32("tv_standard", (int32 *)&tvStandard); 677a10cf76eSAxel Dörfler if (tvStandard == fSelected.tv_standard) { 678a10cf76eSAxel Dörfler if (!item->IsMarked()) 679a10cf76eSAxel Dörfler item->SetMarked(true); 680a10cf76eSAxel Dörfler break; 681a10cf76eSAxel Dörfler } 682a10cf76eSAxel Dörfler } 683a10cf76eSAxel Dörfler 684a10cf76eSAxel Dörfler CheckResolutionMenu(); 685a10cf76eSAxel Dörfler CheckColorMenu(); 686a10cf76eSAxel Dörfler CheckRefreshMenu(); 687a10cf76eSAxel Dörfler 688a10cf76eSAxel Dörfler BString string; 689a10cf76eSAxel Dörfler resolution_to_string(fSelected, string); 690a10cf76eSAxel Dörfler item = fResolutionMenu->FindItem(string.String()); 691a10cf76eSAxel Dörfler 692a10cf76eSAxel Dörfler if (item != NULL) { 693a10cf76eSAxel Dörfler if (!item->IsMarked()) 694a10cf76eSAxel Dörfler item->SetMarked(true); 695a10cf76eSAxel Dörfler } else { 696a10cf76eSAxel Dörfler // this is bad luck - if mode has been set via screen references, 697a10cf76eSAxel Dörfler // this case cannot occur; there are three possible solutions: 698a10cf76eSAxel Dörfler // 1. add a new resolution to list 699a10cf76eSAxel Dörfler // - we had to remove it as soon as a "valid" one is selected 700a10cf76eSAxel Dörfler // - we don't know which frequencies/bit depths are supported 701a10cf76eSAxel Dörfler // - as long as we haven't the GMT formula to create 702a10cf76eSAxel Dörfler // parameters for any resolution given, we cannot 703a10cf76eSAxel Dörfler // really set current mode - it's just not in the list 704a10cf76eSAxel Dörfler // 2. choose nearest resolution 705a10cf76eSAxel Dörfler // - probably a good idea, but implies coding and testing 706a10cf76eSAxel Dörfler // 3. choose lowest resolution 707a10cf76eSAxel Dörfler // - do you really think we are so lazy? yes, we are 708a10cf76eSAxel Dörfler item = fResolutionMenu->ItemAt(0); 709a10cf76eSAxel Dörfler if (item) 710a10cf76eSAxel Dörfler item->SetMarked(true); 711a10cf76eSAxel Dörfler 712a10cf76eSAxel Dörfler // okay - at least we set menu label to active resolution 713a10cf76eSAxel Dörfler fResolutionMenu->Superitem()->SetLabel(string.String()); 714a10cf76eSAxel Dörfler } 715a10cf76eSAxel Dörfler 716a10cf76eSAxel Dörfler // mark active combine mode 717a10cf76eSAxel Dörfler for (int32 i = 0; i < kCombineModeCount; i++) { 718a10cf76eSAxel Dörfler if (kCombineModes[i].mode == fSelected.combine) { 719a10cf76eSAxel Dörfler item = fCombineMenu->ItemAt(i); 720a10cf76eSAxel Dörfler if (item && !item->IsMarked()) 721a10cf76eSAxel Dörfler item->SetMarked(true); 722a10cf76eSAxel Dörfler break; 723a10cf76eSAxel Dörfler } 724a10cf76eSAxel Dörfler } 725a10cf76eSAxel Dörfler 726a10cf76eSAxel Dörfler item = fColorsMenu->ItemAt(0); 727a10cf76eSAxel Dörfler 728a10cf76eSAxel Dörfler for (int32 i = kColorSpaceCount; i-- > 0;) { 729a10cf76eSAxel Dörfler if (kColorSpaces[i].space == fSelected.space) { 730a10cf76eSAxel Dörfler item = fColorsMenu->ItemAt(i); 731a10cf76eSAxel Dörfler break; 732a10cf76eSAxel Dörfler } 733a10cf76eSAxel Dörfler } 734a10cf76eSAxel Dörfler 735a10cf76eSAxel Dörfler if (item && !item->IsMarked()) 736a10cf76eSAxel Dörfler item->SetMarked(true); 737a10cf76eSAxel Dörfler 738a10cf76eSAxel Dörfler string.Truncate(0); 739a10cf76eSAxel Dörfler string << fSelected.BitsPerPixel() << " Bits/Pixel"; 740a10cf76eSAxel Dörfler if (string != fColorsMenu->Superitem()->Label()) 741a10cf76eSAxel Dörfler fColorsMenu->Superitem()->SetLabel(string.String()); 742a10cf76eSAxel Dörfler 743a10cf76eSAxel Dörfler UpdateMonitorView(); 744a10cf76eSAxel Dörfler UpdateRefreshControl(); 745a10cf76eSAxel Dörfler 746a10cf76eSAxel Dörfler CheckApplyEnabled(); 747a10cf76eSAxel Dörfler } 748a10cf76eSAxel Dörfler 749a10cf76eSAxel Dörfler 75012580984SAxel Dörfler /*! Reflect active mode in chosen settings */ 751a10cf76eSAxel Dörfler void 752a10cf76eSAxel Dörfler ScreenWindow::UpdateActiveMode() 753a10cf76eSAxel Dörfler { 75412580984SAxel Dörfler // Usually, this function gets called after a mode 755a10cf76eSAxel Dörfler // has been set manually; still, as the graphics driver 756a10cf76eSAxel Dörfler // is free to fiddle with mode passed, we better ask 757a10cf76eSAxel Dörfler // what kind of mode we actually got 75812580984SAxel Dörfler if (!fVesaApplied) 759a10cf76eSAxel Dörfler fScreenMode.Get(fActive); 760a10cf76eSAxel Dörfler fSelected = fActive; 761a10cf76eSAxel Dörfler 762a10cf76eSAxel Dörfler UpdateControls(); 763a10cf76eSAxel Dörfler } 764a10cf76eSAxel Dörfler 765a10cf76eSAxel Dörfler 766a10cf76eSAxel Dörfler void 767a10cf76eSAxel Dörfler ScreenWindow::ScreenChanged(BRect frame, color_space mode) 768a10cf76eSAxel Dörfler { 769a10cf76eSAxel Dörfler // move window on screen, if necessary 770a10cf76eSAxel Dörfler if (frame.right <= Frame().right 771a10cf76eSAxel Dörfler && frame.bottom <= Frame().bottom) { 772a10cf76eSAxel Dörfler MoveTo((frame.Width() - Frame().Width()) / 2, 773a10cf76eSAxel Dörfler (frame.Height() - Frame().Height()) / 2); 774a10cf76eSAxel Dörfler } 775a10cf76eSAxel Dörfler } 776a10cf76eSAxel Dörfler 777a10cf76eSAxel Dörfler 778a10cf76eSAxel Dörfler void 779a10cf76eSAxel Dörfler ScreenWindow::WorkspaceActivated(int32 workspace, bool state) 780a10cf76eSAxel Dörfler { 781abc649b8SWaldemar Kornewald fScreenMode.GetOriginalMode(fOriginal, workspace); 782a10cf76eSAxel Dörfler UpdateActiveMode(); 783a10cf76eSAxel Dörfler 7846edaa0f6SStefano Ceccherini BMessage message(UPDATE_DESKTOP_COLOR_MSG); 7856edaa0f6SStefano Ceccherini PostMessage(&message, fMonitorView); 786a10cf76eSAxel Dörfler } 787a10cf76eSAxel Dörfler 788a10cf76eSAxel Dörfler 789a10cf76eSAxel Dörfler void 790a10cf76eSAxel Dörfler ScreenWindow::MessageReceived(BMessage* message) 791a10cf76eSAxel Dörfler { 792a10cf76eSAxel Dörfler switch (message->what) { 793a10cf76eSAxel Dörfler case WORKSPACE_CHECK_MSG: 794a10cf76eSAxel Dörfler CheckApplyEnabled(); 795a10cf76eSAxel Dörfler break; 796a10cf76eSAxel Dörfler 797a10cf76eSAxel Dörfler case POP_WORKSPACE_CHANGED_MSG: 798a10cf76eSAxel Dörfler { 799abc649b8SWaldemar Kornewald // update checkpoint state 800a10cf76eSAxel Dörfler int32 index; 801abc649b8SWaldemar Kornewald if (message->FindInt32("index", &index) == B_OK) { 802a10cf76eSAxel Dörfler set_workspace_count(index + 1); 803abc649b8SWaldemar Kornewald CheckApplyEnabled(); 804abc649b8SWaldemar Kornewald } 805a10cf76eSAxel Dörfler break; 806a10cf76eSAxel Dörfler } 807a10cf76eSAxel Dörfler 808a10cf76eSAxel Dörfler case POP_RESOLUTION_MSG: 809a10cf76eSAxel Dörfler { 810a10cf76eSAxel Dörfler message->FindInt32("width", &fSelected.width); 811a10cf76eSAxel Dörfler message->FindInt32("height", &fSelected.height); 812a10cf76eSAxel Dörfler 813a10cf76eSAxel Dörfler CheckColorMenu(); 814a10cf76eSAxel Dörfler CheckRefreshMenu(); 815a10cf76eSAxel Dörfler 816a10cf76eSAxel Dörfler UpdateMonitorView(); 817a10cf76eSAxel Dörfler UpdateRefreshControl(); 818a10cf76eSAxel Dörfler 819a10cf76eSAxel Dörfler CheckApplyEnabled(); 820a10cf76eSAxel Dörfler break; 821a10cf76eSAxel Dörfler } 822a10cf76eSAxel Dörfler 823a10cf76eSAxel Dörfler case POP_COLORS_MSG: 824a10cf76eSAxel Dörfler { 825a10cf76eSAxel Dörfler message->FindInt32("space", (int32 *)&fSelected.space); 826a10cf76eSAxel Dörfler 827a10cf76eSAxel Dörfler BString string; 828a10cf76eSAxel Dörfler string << fSelected.BitsPerPixel() << " Bits/Pixel"; 829a10cf76eSAxel Dörfler fColorsMenu->Superitem()->SetLabel(string.String()); 830a10cf76eSAxel Dörfler 831a10cf76eSAxel Dörfler CheckApplyEnabled(); 832a10cf76eSAxel Dörfler break; 833a10cf76eSAxel Dörfler } 834a10cf76eSAxel Dörfler 835a10cf76eSAxel Dörfler case POP_REFRESH_MSG: 836a40498e2SWaldemar Kornewald { 837a10cf76eSAxel Dörfler message->FindFloat("refresh", &fSelected.refresh); 838a10cf76eSAxel Dörfler fOtherRefresh->SetLabel("Other" B_UTF8_ELLIPSIS); 839a10cf76eSAxel Dörfler // revert "Other…" label - it might have had a refresh rate prefix 840a10cf76eSAxel Dörfler 841a10cf76eSAxel Dörfler CheckApplyEnabled(); 842a10cf76eSAxel Dörfler break; 843a40498e2SWaldemar Kornewald } 844a10cf76eSAxel Dörfler 845a10cf76eSAxel Dörfler case POP_OTHER_REFRESH_MSG: 846a10cf76eSAxel Dörfler { 84729e8a73aSAxel Dörfler // make sure menu shows something useful 848a10cf76eSAxel Dörfler UpdateRefreshControl(); 849a10cf76eSAxel Dörfler 85029e8a73aSAxel Dörfler float min = 0, max = 999; 85129e8a73aSAxel Dörfler fScreenMode.GetRefreshLimits(fSelected, min, max); 85229e8a73aSAxel Dörfler if (min < gMinRefresh) 85329e8a73aSAxel Dörfler min = gMinRefresh; 85429e8a73aSAxel Dörfler if (max > gMaxRefresh) 85529e8a73aSAxel Dörfler max = gMaxRefresh; 85629e8a73aSAxel Dörfler 857c5d10f7aSAxel Dörfler RefreshWindow *fRefreshWindow = new RefreshWindow( 858c5d10f7aSAxel Dörfler fRefreshField->ConvertToScreen(B_ORIGIN), fSelected.refresh, min, max); 859a10cf76eSAxel Dörfler fRefreshWindow->Show(); 860a10cf76eSAxel Dörfler break; 861a10cf76eSAxel Dörfler } 862a10cf76eSAxel Dörfler 863a10cf76eSAxel Dörfler case SET_CUSTOM_REFRESH_MSG: 864a10cf76eSAxel Dörfler { 865a10cf76eSAxel Dörfler // user pressed "done" in "Other…" refresh dialog; 866a10cf76eSAxel Dörfler // select the refresh rate chosen 867a10cf76eSAxel Dörfler message->FindFloat("refresh", &fSelected.refresh); 868a10cf76eSAxel Dörfler 869a10cf76eSAxel Dörfler UpdateRefreshControl(); 870a10cf76eSAxel Dörfler CheckApplyEnabled(); 871a10cf76eSAxel Dörfler break; 872a10cf76eSAxel Dörfler } 873a10cf76eSAxel Dörfler 874a10cf76eSAxel Dörfler case POP_COMBINE_DISPLAYS_MSG: 875a10cf76eSAxel Dörfler { 876a10cf76eSAxel Dörfler // new combine mode has bee chosen 877a10cf76eSAxel Dörfler int32 mode; 878a10cf76eSAxel Dörfler if (message->FindInt32("mode", &mode) == B_OK) 879a10cf76eSAxel Dörfler fSelected.combine = (combine_mode)mode; 880a10cf76eSAxel Dörfler 881a10cf76eSAxel Dörfler CheckResolutionMenu(); 882a10cf76eSAxel Dörfler CheckApplyEnabled(); 883a10cf76eSAxel Dörfler break; 884a10cf76eSAxel Dörfler } 885a10cf76eSAxel Dörfler 886a10cf76eSAxel Dörfler case POP_SWAP_DISPLAYS_MSG: 887a10cf76eSAxel Dörfler message->FindBool("swap", &fSelected.swap_displays); 888a10cf76eSAxel Dörfler CheckApplyEnabled(); 889a10cf76eSAxel Dörfler break; 890a10cf76eSAxel Dörfler 891a10cf76eSAxel Dörfler case POP_USE_LAPTOP_PANEL_MSG: 892a10cf76eSAxel Dörfler message->FindBool("use", &fSelected.use_laptop_panel); 893a10cf76eSAxel Dörfler CheckApplyEnabled(); 894a10cf76eSAxel Dörfler break; 895a10cf76eSAxel Dörfler 896a10cf76eSAxel Dörfler case POP_TV_STANDARD_MSG: 897a10cf76eSAxel Dörfler message->FindInt32("tv_standard", (int32 *)&fSelected.tv_standard); 898a10cf76eSAxel Dörfler CheckApplyEnabled(); 899a10cf76eSAxel Dörfler break; 900a10cf76eSAxel Dörfler 901df3f5bacSStephan Aßmus case BUTTON_LAUNCH_BACKGROUNDS_MSG: 9026f095d6aSRyan Leavengood if (be_roster->Launch(kBackgroundsSignature) == B_ALREADY_RUNNING) { 9036f095d6aSRyan Leavengood app_info info; 9046f095d6aSRyan Leavengood be_roster->GetAppInfo(kBackgroundsSignature, &info); 9056f095d6aSRyan Leavengood be_roster->ActivateApp(info.team); 9066f095d6aSRyan Leavengood } 907df3f5bacSStephan Aßmus break; 908df3f5bacSStephan Aßmus 909a10cf76eSAxel Dörfler case BUTTON_DEFAULTS_MSG: 910a10cf76eSAxel Dörfler { 9114be51fe3SWaldemar Kornewald // TODO: get preferred settings of screen 912a10cf76eSAxel Dörfler fSelected.width = 640; 913a10cf76eSAxel Dörfler fSelected.height = 480; 914a10cf76eSAxel Dörfler fSelected.space = B_CMAP8; 915a10cf76eSAxel Dörfler fSelected.refresh = 60.0; 916a10cf76eSAxel Dörfler fSelected.combine = kCombineDisable; 917a10cf76eSAxel Dörfler fSelected.swap_displays = false; 918a10cf76eSAxel Dörfler fSelected.use_laptop_panel = false; 919a10cf76eSAxel Dörfler fSelected.tv_standard = 0; 920a10cf76eSAxel Dörfler 921abc649b8SWaldemar Kornewald BMenuItem *item; 922abc649b8SWaldemar Kornewald item = fWorkspaceCountField->Menu()->ItemAt(3); 923abc649b8SWaldemar Kornewald if (item != NULL) 924abc649b8SWaldemar Kornewald item->SetMarked(true); 925abc649b8SWaldemar Kornewald 926a10cf76eSAxel Dörfler UpdateControls(); 927a10cf76eSAxel Dörfler break; 928a10cf76eSAxel Dörfler } 929a10cf76eSAxel Dörfler 93010e9b12fSWaldemar Kornewald case BUTTON_UNDO_MSG: 931abc649b8SWaldemar Kornewald fTempScreenMode.Revert(); 932abc649b8SWaldemar Kornewald UpdateActiveMode(); 933abc649b8SWaldemar Kornewald break; 934abc649b8SWaldemar Kornewald 935abc649b8SWaldemar Kornewald case BUTTON_REVERT_MSG: 936abc649b8SWaldemar Kornewald { 937abc649b8SWaldemar Kornewald fModified = false; 938abc649b8SWaldemar Kornewald BMenuItem *item; 939abc649b8SWaldemar Kornewald item = fWorkspaceCountField->Menu()->ItemAt(fOriginalWorkspaceCount - 1); 940abc649b8SWaldemar Kornewald if (item != NULL) 941abc649b8SWaldemar Kornewald item->SetMarked(true); 942abc649b8SWaldemar Kornewald 943abc649b8SWaldemar Kornewald // ScreenMode::Revert() assumes that we first set the correct number 944abc649b8SWaldemar Kornewald // of workspaces 945abc649b8SWaldemar Kornewald set_workspace_count(fOriginalWorkspaceCount); 946a10cf76eSAxel Dörfler fScreenMode.Revert(); 947a10cf76eSAxel Dörfler UpdateActiveMode(); 948a10cf76eSAxel Dörfler break; 949abc649b8SWaldemar Kornewald } 950a10cf76eSAxel Dörfler 951a10cf76eSAxel Dörfler case BUTTON_APPLY_MSG: 952a10cf76eSAxel Dörfler Apply(); 953a10cf76eSAxel Dörfler break; 954a10cf76eSAxel Dörfler 955abc649b8SWaldemar Kornewald case MAKE_INITIAL_MSG: 956abc649b8SWaldemar Kornewald // user pressed "keep" in confirmation dialog 957abc649b8SWaldemar Kornewald fModified = true; 958a10cf76eSAxel Dörfler UpdateActiveMode(); 959a10cf76eSAxel Dörfler break; 960a10cf76eSAxel Dörfler 961a10cf76eSAxel Dörfler default: 962a10cf76eSAxel Dörfler BWindow::MessageReceived(message); 963a10cf76eSAxel Dörfler break; 964a10cf76eSAxel Dörfler } 965a10cf76eSAxel Dörfler } 966a10cf76eSAxel Dörfler 967a10cf76eSAxel Dörfler 96812580984SAxel Dörfler status_t 96912580984SAxel Dörfler ScreenWindow::_WriteVesaModeFile(const screen_mode& mode) const 97012580984SAxel Dörfler { 97112580984SAxel Dörfler BPath path; 97212580984SAxel Dörfler status_t status = find_directory(B_USER_SETTINGS_DIRECTORY, &path, true); 97312580984SAxel Dörfler if (status < B_OK) 97412580984SAxel Dörfler return status; 97512580984SAxel Dörfler 97612580984SAxel Dörfler path.Append("kernel/drivers"); 97712580984SAxel Dörfler status = create_directory(path.Path(), 0755); 97812580984SAxel Dörfler if (status < B_OK) 97912580984SAxel Dörfler return status; 98012580984SAxel Dörfler 98112580984SAxel Dörfler path.Append("vesa"); 98212580984SAxel Dörfler BFile file; 98312580984SAxel Dörfler status = file.SetTo(path.Path(), B_CREATE_FILE | B_WRITE_ONLY | B_ERASE_FILE); 98412580984SAxel Dörfler if (status < B_OK) 98512580984SAxel Dörfler return status; 98612580984SAxel Dörfler 98712580984SAxel Dörfler char buffer[256]; 98812580984SAxel Dörfler snprintf(buffer, sizeof(buffer), "mode %ld %ld %ld\n", 98912580984SAxel Dörfler mode.width, mode.height, mode.BitsPerPixel()); 99012580984SAxel Dörfler 99112580984SAxel Dörfler ssize_t bytesWritten = file.Write(buffer, strlen(buffer)); 99212580984SAxel Dörfler if (bytesWritten < B_OK) 99312580984SAxel Dörfler return bytesWritten; 99412580984SAxel Dörfler 99512580984SAxel Dörfler return B_OK; 99612580984SAxel Dörfler } 99712580984SAxel Dörfler 99812580984SAxel Dörfler 999a10cf76eSAxel Dörfler bool 1000a10cf76eSAxel Dörfler ScreenWindow::CanApply() const 1001a10cf76eSAxel Dörfler { 1002894deb54SWaldemar Kornewald return fAllWorkspacesItem->IsMarked() || fSelected != fActive; 1003a10cf76eSAxel Dörfler } 1004a10cf76eSAxel Dörfler 1005a10cf76eSAxel Dörfler 1006a10cf76eSAxel Dörfler bool 1007a10cf76eSAxel Dörfler ScreenWindow::CanRevert() const 1008a10cf76eSAxel Dörfler { 1009abc649b8SWaldemar Kornewald return fSelected != fActive || count_workspaces() != fOriginalWorkspaceCount 1010abc649b8SWaldemar Kornewald || fModified; 1011a10cf76eSAxel Dörfler } 1012a10cf76eSAxel Dörfler 1013a10cf76eSAxel Dörfler 1014a10cf76eSAxel Dörfler void 1015a10cf76eSAxel Dörfler ScreenWindow::CheckApplyEnabled() 1016a10cf76eSAxel Dörfler { 1017a10cf76eSAxel Dörfler fApplyButton->SetEnabled(CanApply()); 1018a10cf76eSAxel Dörfler fRevertButton->SetEnabled(CanRevert()); 1019a10cf76eSAxel Dörfler } 1020a10cf76eSAxel Dörfler 1021a10cf76eSAxel Dörfler 1022a10cf76eSAxel Dörfler void 1023abc649b8SWaldemar Kornewald ScreenWindow::UpdateOriginal() 1024abc649b8SWaldemar Kornewald { 1025abc649b8SWaldemar Kornewald fOriginalWorkspaceCount = count_workspaces(); 1026abc649b8SWaldemar Kornewald fScreenMode.Get(fOriginal); 1027abc649b8SWaldemar Kornewald fScreenMode.UpdateOriginalModes(); 1028abc649b8SWaldemar Kornewald } 1029abc649b8SWaldemar Kornewald 1030abc649b8SWaldemar Kornewald 1031abc649b8SWaldemar Kornewald void 1032a10cf76eSAxel Dörfler ScreenWindow::Apply() 1033a10cf76eSAxel Dörfler { 103412580984SAxel Dörfler if (_IsVesa()) { 103512580984SAxel Dörfler (new BAlert("VesaAlert", 103612580984SAxel Dörfler "Your graphics card is not supported. Resolution changes will be " 103712580984SAxel Dörfler "adopted on next system startup.\n", "Okay", NULL, NULL, B_WIDTH_AS_USUAL, 103812580984SAxel Dörfler B_INFO_ALERT))->Go(NULL); 103912580984SAxel Dörfler 104012580984SAxel Dörfler fVesaApplied = true; 104112580984SAxel Dörfler fActive = fSelected; 104212580984SAxel Dörfler return; 104312580984SAxel Dörfler } 104412580984SAxel Dörfler 1045abc649b8SWaldemar Kornewald // make checkpoint, so we can undo these changes 1046abc649b8SWaldemar Kornewald fTempScreenMode.UpdateOriginalModes(); 104707184a9eSAxel Dörfler status_t status = fScreenMode.Set(fSelected); 104807184a9eSAxel Dörfler if (status == B_OK) { 1049abc649b8SWaldemar Kornewald // use the mode that has eventually been set and 1050abc649b8SWaldemar Kornewald // thus we know to be working; it can differ from 1051abc649b8SWaldemar Kornewald // the mode selected by user due to hardware limitation 1052abc649b8SWaldemar Kornewald display_mode newMode; 1053abc649b8SWaldemar Kornewald BScreen screen(this); 1054abc649b8SWaldemar Kornewald screen.GetMode(&newMode); 1055abc649b8SWaldemar Kornewald 1056abc649b8SWaldemar Kornewald if (fAllWorkspacesItem->IsMarked()) { 1057abc649b8SWaldemar Kornewald int32 originatingWorkspace = current_workspace(); 1058abc649b8SWaldemar Kornewald for (int32 i = 0; i < count_workspaces(); i++) { 1059abc649b8SWaldemar Kornewald if (i != originatingWorkspace) 1060abc649b8SWaldemar Kornewald screen.SetMode(i, &newMode, true); 1061abc649b8SWaldemar Kornewald } 1062abc649b8SWaldemar Kornewald } 1063abc649b8SWaldemar Kornewald 1064a10cf76eSAxel Dörfler fActive = fSelected; 1065a10cf76eSAxel Dörfler 1066abc649b8SWaldemar Kornewald // TODO: only show alert when this is an unknown mode 1067a10cf76eSAxel Dörfler BWindow* window = new AlertWindow(this); 1068a10cf76eSAxel Dörfler window->Show(); 106907184a9eSAxel Dörfler } else { 107007184a9eSAxel Dörfler char message[256]; 107107184a9eSAxel Dörfler snprintf(message, sizeof(message), 107207184a9eSAxel Dörfler "The screen mode could not be set:\n\t%s\n", screen_errors(status)); 107307184a9eSAxel Dörfler BAlert* alert = new BAlert("Screen Alert", message, "Okay", NULL, NULL, 107407184a9eSAxel Dörfler B_WIDTH_AS_USUAL, B_WARNING_ALERT); 107507184a9eSAxel Dörfler alert->Go(); 1076a10cf76eSAxel Dörfler } 107707184a9eSAxel Dörfler } 107807184a9eSAxel Dörfler 1079df3f5bacSStephan Aßmus 1080df3f5bacSStephan Aßmus void 1081df3f5bacSStephan Aßmus ScreenWindow::LayoutControls(uint32 flags) 1082df3f5bacSStephan Aßmus { 1083df3f5bacSStephan Aßmus // layout the screen box and its controls 1084df3f5bacSStephan Aßmus fWorkspaceCountField->ResizeToPreferred(); 1085df3f5bacSStephan Aßmus 1086df3f5bacSStephan Aßmus float monitorViewHeight = fMonitorView->Bounds().Height(); 1087df3f5bacSStephan Aßmus float workspaceFieldHeight = fWorkspaceCountField->Bounds().Height(); 1088df3f5bacSStephan Aßmus float backgroundsButtonHeight = fBackgroundsButton->Bounds().Height(); 1089df3f5bacSStephan Aßmus 1090df3f5bacSStephan Aßmus float screenBoxWidth = fWorkspaceCountField->Bounds().Width() + 20.0; 1091df3f5bacSStephan Aßmus float screenBoxHeight = monitorViewHeight + 5.0 1092df3f5bacSStephan Aßmus + workspaceFieldHeight + 5.0 1093df3f5bacSStephan Aßmus + backgroundsButtonHeight 1094df3f5bacSStephan Aßmus + 20.0; 1095df3f5bacSStephan Aßmus 109629e8a73aSAxel Dörfler #ifdef __HAIKU__ 1097df3f5bacSStephan Aßmus fScreenBox->MoveTo(10.0, 10.0 + fControlsBox->TopBorderOffset()); 109829e8a73aSAxel Dörfler #else 109929e8a73aSAxel Dörfler fScreenBox->MoveTo(10.0, 10.0 + 3); 110029e8a73aSAxel Dörfler #endif 1101df3f5bacSStephan Aßmus fScreenBox->ResizeTo(screenBoxWidth, screenBoxHeight); 1102df3f5bacSStephan Aßmus 1103df3f5bacSStephan Aßmus float leftOffset = 10.0; 1104df3f5bacSStephan Aßmus float topOffset = 10.0; 1105df3f5bacSStephan Aßmus fMonitorView->MoveTo(leftOffset, topOffset); 1106df3f5bacSStephan Aßmus fMonitorView->ResizeTo(screenBoxWidth - 20.0, monitorViewHeight); 1107df3f5bacSStephan Aßmus fMonitorView->SetResizingMode(B_FOLLOW_ALL); 1108df3f5bacSStephan Aßmus topOffset += monitorViewHeight + 5.0; 1109df3f5bacSStephan Aßmus 1110df3f5bacSStephan Aßmus fWorkspaceCountField->MoveTo(leftOffset, topOffset); 1111df3f5bacSStephan Aßmus fWorkspaceCountField->SetResizingMode(B_FOLLOW_LEFT_RIGHT | B_FOLLOW_BOTTOM); 1112df3f5bacSStephan Aßmus topOffset += workspaceFieldHeight + 5.0; 1113df3f5bacSStephan Aßmus 1114df3f5bacSStephan Aßmus fBackgroundsButton->MoveTo(leftOffset, topOffset); 1115df3f5bacSStephan Aßmus fBackgroundsButton->ResizeTo(screenBoxWidth - 20.0, backgroundsButtonHeight); 1116df3f5bacSStephan Aßmus fBackgroundsButton->SetResizingMode(B_FOLLOW_LEFT_RIGHT | B_FOLLOW_BOTTOM); 1117df3f5bacSStephan Aßmus 1118df3f5bacSStephan Aßmus fControlsBox->MoveTo(fScreenBox->Frame().right + 10.0, 10.0); 1119df3f5bacSStephan Aßmus 1120df3f5bacSStephan Aßmus // layout the right side 11214008594dSWaldemar Kornewald fApplyButton->ResizeToPreferred(); 1122df3f5bacSStephan Aßmus BRect controlsRect = LayoutMenuFields(flags); 1123df3f5bacSStephan Aßmus controlsRect.InsetBy(-10.0, -10.0); 11244008594dSWaldemar Kornewald controlsRect.bottom += 8 + fApplyButton->Bounds().Height(); 1125df3f5bacSStephan Aßmus // adjust size of controls box and move aligned buttons along 1126df3f5bacSStephan Aßmus float xDiff = controlsRect.right - fControlsBox->Bounds().right; 1127df3f5bacSStephan Aßmus float yDiff = controlsRect.bottom - fControlsBox->Bounds().bottom; 1128df3f5bacSStephan Aßmus if (yDiff < 0.0) { 1129df3f5bacSStephan Aßmus // don't shrink vertically 1130df3f5bacSStephan Aßmus yDiff = 0.0; 1131df3f5bacSStephan Aßmus } 1132df3f5bacSStephan Aßmus 1133df3f5bacSStephan Aßmus fControlsBox->ResizeBy(xDiff, yDiff); 1134df3f5bacSStephan Aßmus 1135df3f5bacSStephan Aßmus // align bottom of boxen 1136df3f5bacSStephan Aßmus float boxBottomDiff = fControlsBox->Frame().bottom - fScreenBox->Frame().bottom; 1137df3f5bacSStephan Aßmus if (boxBottomDiff > 0) 1138df3f5bacSStephan Aßmus fScreenBox->ResizeBy(0.0, boxBottomDiff); 1139df3f5bacSStephan Aßmus else 1140df3f5bacSStephan Aßmus fControlsBox->ResizeBy(0.0, -boxBottomDiff); 1141df3f5bacSStephan Aßmus 1142df3f5bacSStephan Aßmus BRect boxFrame = fScreenBox->Frame() | fControlsBox->Frame(); 1143df3f5bacSStephan Aßmus 1144df3f5bacSStephan Aßmus // layout rest of buttons 1145abc649b8SWaldemar Kornewald // TODO: we don't support getting the screen's preferred settings 1146abc649b8SWaldemar Kornewald // fDefaultsButton->ResizeToPreferred(); 1147abc649b8SWaldemar Kornewald // fDefaultsButton->MoveTo(boxFrame.left, boxFrame.bottom + 8); 1148df3f5bacSStephan Aßmus 1149df3f5bacSStephan Aßmus fRevertButton->ResizeToPreferred(); 1150abc649b8SWaldemar Kornewald fRevertButton->MoveTo(boxFrame.left, boxFrame.bottom + 8); 1151abc649b8SWaldemar Kornewald // fRevertButton->MoveTo(fDefaultsButton->Frame().right + 10, 1152abc649b8SWaldemar Kornewald // fDefaultsButton->Frame().top); 1153df3f5bacSStephan Aßmus 11544008594dSWaldemar Kornewald // Apply button was already resized above 1155abc649b8SWaldemar Kornewald float resolutionFieldRight = fResolutionField->Frame().right; 1156abc649b8SWaldemar Kornewald fApplyButton->MoveTo(resolutionFieldRight - fApplyButton->Bounds().Width(), 11574008594dSWaldemar Kornewald fControlsBox->Bounds().bottom - fApplyButton->Bounds().Height() - 10); 1158df3f5bacSStephan Aßmus 1159abc649b8SWaldemar Kornewald ResizeTo(boxFrame.right + 10, fRevertButton->Frame().bottom + 10); 1160df3f5bacSStephan Aßmus } 1161df3f5bacSStephan Aßmus 1162df3f5bacSStephan Aßmus 1163df3f5bacSStephan Aßmus BRect 1164df3f5bacSStephan Aßmus ScreenWindow::LayoutMenuFields(uint32 flags, bool sideBySide) 1165df3f5bacSStephan Aßmus { 1166df3f5bacSStephan Aßmus BList menuFields; 1167df3f5bacSStephan Aßmus menuFields.AddItem((void*)fResolutionField); 1168df3f5bacSStephan Aßmus menuFields.AddItem((void*)fColorsField); 1169df3f5bacSStephan Aßmus menuFields.AddItem((void*)fRefreshField); 1170df3f5bacSStephan Aßmus 1171df3f5bacSStephan Aßmus BRect frame; 1172df3f5bacSStephan Aßmus 1173df3f5bacSStephan Aßmus if (sideBySide) 1174df3f5bacSStephan Aßmus frame = stack_and_align_menu_fields(menuFields); 1175df3f5bacSStephan Aßmus 1176df3f5bacSStephan Aßmus if (sideBySide) 1177df3f5bacSStephan Aßmus menuFields.MakeEmpty(); 1178df3f5bacSStephan Aßmus 1179df3f5bacSStephan Aßmus if (flags & SHOW_COMBINE_FIELD) 1180df3f5bacSStephan Aßmus menuFields.AddItem((void*)fCombineField); 1181df3f5bacSStephan Aßmus if (flags & SHOW_SWAP_FIELD) 1182df3f5bacSStephan Aßmus menuFields.AddItem((void*)fSwapDisplaysField); 1183df3f5bacSStephan Aßmus if (flags & SHOW_LAPTOP_PANEL_FIELD) 1184df3f5bacSStephan Aßmus menuFields.AddItem((void*)fUseLaptopPanelField); 1185df3f5bacSStephan Aßmus if (flags & SHOW_TV_STANDARD_FIELD) 1186df3f5bacSStephan Aßmus menuFields.AddItem((void*)fTVStandardField); 1187df3f5bacSStephan Aßmus 1188df3f5bacSStephan Aßmus if (sideBySide) { 1189df3f5bacSStephan Aßmus if (menuFields.CountItems() > 0) { 1190df3f5bacSStephan Aßmus ((BMenuField*)menuFields.FirstItem())->MoveTo(frame.right + 8.0, frame.top); 1191df3f5bacSStephan Aßmus frame = frame | stack_and_align_menu_fields(menuFields); 1192df3f5bacSStephan Aßmus } 1193df3f5bacSStephan Aßmus } else { 1194df3f5bacSStephan Aßmus frame = stack_and_align_menu_fields(menuFields); 1195df3f5bacSStephan Aßmus } 1196df3f5bacSStephan Aßmus 1197df3f5bacSStephan Aßmus return frame; 1198df3f5bacSStephan Aßmus } 1199df3f5bacSStephan Aßmus 1200