diff --git a/src/servers/app/Desktop.cpp b/src/servers/app/Desktop.cpp index 35b9678a30..1569550381 100644 --- a/src/servers/app/Desktop.cpp +++ b/src/servers/app/Desktop.cpp @@ -280,6 +280,7 @@ Desktop::Desktop(uid_t userID) for (int32 i = 0; i < kMaxWorkspaces; i++) { _Windows(i).SetIndex(i); + fWorkspaces[i].RestoreConfiguration(*fSettings->WorkspacesMessage(i)); } fMessagePort = create_port(DEFAULT_MONITOR_PORT_SIZE, name); @@ -725,7 +726,7 @@ Desktop::SetWorkspace(int32 index) void -Desktop::ScreenChanged(Screen* screen) +Desktop::ScreenChanged(Screen* screen, bool makeDefault) { // TODO: confirm that everywhere this is used, // the Window WriteLock is held @@ -758,6 +759,16 @@ Desktop::ScreenChanged(Screen* screen) window = window->NextWindow(kAllWindowList)) { window->ServerWindow()->SendMessageToClient(&update); } + + if (makeDefault) { + // store settings + BMessage settings; + fVirtualScreen.StoreConfiguration(settings); + fWorkspaces[fCurrentWorkspace].StoreConfiguration(settings); + + fSettings->SetWorkspacesMessage(fCurrentWorkspace, settings); + fSettings->Save(kWorkspacesSettings); + } } diff --git a/src/servers/app/Desktop.h b/src/servers/app/Desktop.h index 9689d2e2a0..fad10e599f 100644 --- a/src/servers/app/Desktop.h +++ b/src/servers/app/Desktop.h @@ -76,7 +76,7 @@ class Desktop : public MessageLooper, public ScreenOwner { void SetCursor(ServerCursor* cursor); ServerCursor* Cursor() const; - void ScreenChanged(Screen* screen); + void ScreenChanged(Screen* screen, bool makeDefault); void ScreenRemoved(Screen* screen) {} void ScreenAdded(Screen* screen) {} diff --git a/src/servers/app/DesktopSettings.cpp b/src/servers/app/DesktopSettings.cpp index 581ebd645a..695742b7e5 100644 --- a/src/servers/app/DesktopSettings.cpp +++ b/src/servers/app/DesktopSettings.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2005, Haiku. + * Copyright 2005-2006, Haiku. * Distributed under the terms of the MIT License. * * Authors: @@ -14,6 +14,12 @@ #include "FontManager.h" #include "ServerConfig.h" +#include +#include +#include +//#include +#include + DesktopSettings::Private::Private() : BLocker("DesktopSettings_Private") @@ -60,18 +66,88 @@ DesktopSettings::Private::_SetDefaults() } +status_t +DesktopSettings::Private::_GetPath(BPath& path) +{ + status_t status = find_directory(B_USER_SETTINGS_DIRECTORY, &path); + if (status < B_OK) + return status; + + status = path.Append("system/app_server"); + if (status < B_OK) + return status; + + return create_directory(path.Path(), 0755); +} + + status_t DesktopSettings::Private::_Load() { // TODO: add support for old app_server_settings file as well + + BPath basePath; + status_t status = _GetPath(basePath); + if (status < B_OK) + return status; + + // read workspaces settings + + BPath path(basePath); + path.Append("workspaces"); + + BFile file; + status = file.SetTo(path.Path(), B_READ_ONLY); + if (status == B_OK) { + BMessage settings; + status = settings.Unflatten(&file); + if (status == B_OK) { + int32 count; + if (settings.FindInt32("count", &count) == B_OK) { + fWorkspacesCount = count; + if (fWorkspacesCount < 1 || fWorkspacesCount > 32) + fWorkspacesCount = 4; + } + + int32 i = 0; + while (i < 32 + && settings.FindMessage("workspace", i, &fWorkspaceMessages[i]) == B_OK) { + i++; + } + } + } + return B_ERROR; } status_t -DesktopSettings::Private::Save() +DesktopSettings::Private::Save(uint32 mask) { - return B_ERROR; + BPath basePath; + status_t status = _GetPath(basePath); + if (status < B_OK) + return status; + + if (mask & kWorkspacesSettings) { + BPath path(basePath); + if (path.Append("workspaces") == B_OK) { + BMessage settings('asws'); + settings.AddInt32("count", fWorkspacesCount); + + for (int32 i = 0; i < kMaxWorkspaces; i++) { + settings.AddMessage("workspace", &fWorkspaceMessages[i]); + } + + BFile file; + status = file.SetTo(path.Path(), B_CREATE_FILE | B_ERASE_FILE | B_READ_WRITE); + if (status == B_OK) { + status = settings.Flatten(&file, NULL); + } + } + } + + return status; } diff --git a/src/servers/app/DesktopSettings.h b/src/servers/app/DesktopSettings.h index 12cc6fc9e2..475c6024b9 100644 --- a/src/servers/app/DesktopSettings.h +++ b/src/servers/app/DesktopSettings.h @@ -19,13 +19,19 @@ class ServerFont; static const int32 kMaxWorkspaces = 32; +enum { + kAllSettings = 0xff, + kWorkspacesSettings = 0x01, + kFontSettings = 0x02, + kAppearanceSettings = 0x04 +}; class DesktopSettings { public: DesktopSettings(Desktop* desktop); ~DesktopSettings(); - status_t Save(); + status_t Save(uint32 mask = kAllSettings); void SetDefaultPlainFont(const ServerFont& font); void GetDefaultPlainFont(ServerFont& font) const; diff --git a/src/servers/app/DesktopSettingsPrivate.h b/src/servers/app/DesktopSettingsPrivate.h index 0da8e2f8e1..662f7af529 100644 --- a/src/servers/app/DesktopSettingsPrivate.h +++ b/src/servers/app/DesktopSettingsPrivate.h @@ -1,5 +1,5 @@ /* - * Copyright 2001-2005, Haiku. + * Copyright 2005-2006, Haiku. * Distributed under the terms of the MIT License. * * Authors: @@ -20,7 +20,7 @@ class DesktopSettings::Private : public BLocker { Private(); ~Private(); - status_t Save(); + status_t Save(uint32 mask = kAllSettings); void SetDefaultPlainFont(const ServerFont& font); const ServerFont& DefaultPlainFont() const; @@ -50,6 +50,7 @@ class DesktopSettings::Private : public BLocker { private: void _SetDefaults(); status_t _Load(); + status_t _GetPath(BPath& path); ServerFont fPlainFont; ServerFont fBoldFont; diff --git a/src/servers/app/ServerApp.cpp b/src/servers/app/ServerApp.cpp index 53a8739d4a..cbcf7ecd52 100644 --- a/src/servers/app/ServerApp.cpp +++ b/src/servers/app/ServerApp.cpp @@ -2079,18 +2079,18 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) display_mode mode; link.Read(&mode); - bool makedefault = false; - link.Read(&makedefault); + bool makeDefault = false; + status_t status = link.Read(&makeDefault); - status_t status = B_ERROR; - if (fDesktop->LockAllWindows()) { - status = fDesktop->ScreenAt(0)->SetMode(mode); + if (status == B_OK && fDesktop->LockAllWindows()) { + status = fDesktop->ScreenAt(0)->SetMode(mode, makeDefault); if (status == B_OK) { gInputManager->UpdateScreenBounds(fDesktop->ScreenAt(0)->Frame()); - fDesktop->ScreenChanged(fDesktop->ScreenAt(0)); + fDesktop->ScreenChanged(fDesktop->ScreenAt(0), makeDefault); } fDesktop->UnlockAllWindows(); - } + } else + status = B_ERROR; fLink.StartMessage(status); fLink.Flush(); diff --git a/src/servers/app/ServerScreen.cpp b/src/servers/app/ServerScreen.cpp index b16ced15b9..3ef9b70460 100644 --- a/src/servers/app/ServerScreen.cpp +++ b/src/servers/app/ServerScreen.cpp @@ -25,7 +25,8 @@ Screen::Screen(::HWInterface *interface, int32 id) : fID(id), fDriver(interface ? new DrawingEngine(interface) : NULL), - fHWInterface(interface) + fHWInterface(interface), + fIsDefault(true) { } @@ -33,7 +34,8 @@ Screen::Screen(::HWInterface *interface, int32 id) Screen::Screen() : fID(-1), fDriver(NULL), - fHWInterface(NULL) + fHWInterface(NULL), + fIsDefault(true) { } @@ -49,12 +51,12 @@ Screen::~Screen() status_t Screen::Initialize() { - status_t ret = B_NO_INIT; if (fDriver) { // this will also init the graphics hardware the driver is attached to - ret = fDriver->Initialize(); + return fDriver->Initialize(); } - return ret; + + return B_NO_INIT; } @@ -67,39 +69,38 @@ Screen::Shutdown() status_t -Screen::SetMode(display_mode mode) +Screen::SetMode(display_mode mode, bool makeDefault) { - status_t ret = fHWInterface->SetMode(mode); + status_t status = fHWInterface->SetMode(mode); // the DrawingEngine needs to adjust itself - if (ret >= B_OK) + if (status >= B_OK) { fDriver->Update(); + fIsDefault = makeDefault; + } - return ret; + return status; } status_t Screen::SetMode(uint16 width, uint16 height, uint32 colorspace, - float frequency) + float frequency, bool makeDefault) { - status_t ret = B_ERROR; - // search for a matching mode display_mode mode; - ret = _FindMode(width, height, colorspace, frequency, &mode); - - if (ret < B_OK) { + status_t status = _FindMode(width, height, colorspace, frequency, &mode); + if (status < B_OK) { // TODO: Move fallback elsewhere, this function should simply // fail if requested to set unsupported mode. // Ups. Not good. Ignore the requested mode and use fallback params. - ret = _FindMode(640, 480, B_CMAP8, 60.0, &mode); + status = _FindMode(640, 480, B_CMAP8, 60.0, &mode); } - if (ret >= B_OK) - ret = SetMode(mode); + if (status >= B_OK) + status = SetMode(mode, makeDefault); - return ret; + return status; } @@ -152,8 +153,8 @@ Screen::_FindMode(uint16 width, uint16 height, uint32 colorspace, display_mode* dm = NULL; uint32 count; - status_t err = fHWInterface->GetModeList(&dm, &count); - if (err < B_OK || count <= 0) { + status_t status = fHWInterface->GetModeList(&dm, &count); + if (status < B_OK || count <= 0) { // We've run into quite a problem here! This is a function which is a requirement // for a graphics module. The best thing that we can hope for is 640x480x8 without // knowing anything else. While even this seems like insanity to assume that we @@ -162,7 +163,7 @@ Screen::_FindMode(uint16 width, uint16 height, uint32 colorspace, if (width == 640 && height == 480 && colorspace == B_CMAP8) return B_OK; - return err; + return status; } #ifndef HAIKU_TARGET_PLATFORM_LIBBE_TEST diff --git a/src/servers/app/ServerScreen.h b/src/servers/app/ServerScreen.h index 1a47349388..4f324e2338 100644 --- a/src/servers/app/ServerScreen.h +++ b/src/servers/app/ServerScreen.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001-2005, Haiku, Inc. + * Copyright (c) 2001-2006, Haiku, Inc. * Distributed under the terms of the MIT license. * * Authors: @@ -7,8 +7,8 @@ * Axel Dörfler, axeld@pinc-software.de * Stephan Aßmus, */ -#ifndef _SCREEN_H_ -#define _SCREEN_H_ +#ifndef SCREEN_H +#define SCREEN_H #include @@ -28,14 +28,13 @@ class Screen { status_t Initialize(); void Shutdown(); - void SetID(int32 ID) - { fID = ID; } + int32 ID() const { return fID; } + + status_t SetMode(display_mode mode, bool makeDefault); + status_t SetMode(uint16 width, uint16 height, + uint32 colorspace, float frequency, + bool makeDefault); - status_t SetMode(display_mode mode); - status_t SetMode(uint16 width, - uint16 height, - uint32 colorspace, - float frequency); void GetMode(display_mode* mode) const; void GetMode(uint16 &width, uint16 &height, @@ -44,8 +43,7 @@ class Screen { BRect Frame() const; color_space ColorSpace() const; - inline int32 ScreenNumber() const - { return fID; } + bool IsDefaultMode() const { return fIsDefault; } inline DrawingEngine* GetDrawingEngine() const { return fDriver; } @@ -67,6 +65,7 @@ class Screen { int32 fID; DrawingEngine* fDriver; ::HWInterface* fHWInterface; + bool fIsDefault; }; -#endif /* _SCREEN_H_ */ +#endif /* SCREEN_H */ diff --git a/src/servers/app/VirtualScreen.cpp b/src/servers/app/VirtualScreen.cpp index b7163aeb7c..e8c198bcd9 100644 --- a/src/servers/app/VirtualScreen.cpp +++ b/src/servers/app/VirtualScreen.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2005, Haiku. + * Copyright 2005-2006, Haiku. * Distributed under the terms of the MIT License. * * Authors: @@ -81,7 +81,31 @@ VirtualScreen::RestoreConfiguration(Desktop& desktop, const BMessage* settings) status_t VirtualScreen::StoreConfiguration(BMessage& settings) { - // TODO: implement me + for (int32 i = 0; i < fScreenList.CountItems(); i++) { + screen_item* item = fScreenList.ItemAt(i); + Screen* screen = item->screen; + if (!screen->IsDefaultMode()) + continue; + + BMessage screenSettings; + screenSettings.AddInt32("id", screen->ID()); + //screenSettings.AddString("name", "-"); + screenSettings.AddRect("frame", item->frame); + + // TODO: or just store a display_mode completely? + uint16 width, height; + uint32 colorSpace; + float frequency; + screen->GetMode(width, height, colorSpace, frequency); + + screenSettings.AddInt32("width", width); + screenSettings.AddInt32("height", height); + screenSettings.AddInt32("color space", colorSpace); + screenSettings.AddFloat("frequency", frequency); + + settings.AddMessage("screen", &screenSettings); + } + return B_OK; } @@ -95,12 +119,21 @@ VirtualScreen::AddScreen(Screen* screen) item->screen = screen; + status_t status = B_ERROR; BMessage settings; if (_FindConfiguration(screen, settings) == B_OK) { - // TODO: read from settings! - } else { + // we found settings for this screen, and try to apply them now + int32 width, height, colorSpace; + float frequency; + if (settings.FindInt32("width", &width) == B_OK + && settings.FindInt32("height", &height) == B_OK + && settings.FindInt32("color space", &colorSpace) == B_OK + && settings.FindFloat("frequency", &frequency) == B_OK) + status = screen->SetMode(width, height, colorSpace, frequency, true); + } + if (status < B_OK) { // TODO: more intelligent standard mode (monitor preference, desktop default, ...) - screen->SetMode(800, 600, B_RGB32, 60.f); + screen->SetMode(800, 600, B_RGB32, 60.f, false); } // TODO: this works only for single screen configurations @@ -166,6 +199,19 @@ VirtualScreen::_FindConfiguration(Screen* screen, BMessage& settings) { // TODO: we probably want to identify the resolution by connected monitor, // and not the display driver used... - return B_ERROR; + // For now, we just use the screen ID, which is almost nothing, anyway... + + uint32 i = 0; + while (fSettings.FindMessage("screen", i++, &settings) == B_OK) { + int32 id; + if (settings.FindInt32("id", &id) != B_OK + || screen->ID() != id) + continue; + + // we found our match + return B_OK; + } + + return B_NAME_NOT_FOUND; } diff --git a/src/servers/app/Workspace.cpp b/src/servers/app/Workspace.cpp index c5ebf6e0b8..4e5bd2a383 100644 --- a/src/servers/app/Workspace.cpp +++ b/src/servers/app/Workspace.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2005, Haiku. + * Copyright 2005-2006, Haiku. * Distributed under the terms of the MIT License. * * Authors: @@ -45,14 +45,19 @@ Workspace::Private::SetColor(const RGBColor& color) void -Workspace::Private::SetSettings(BMessage& settings) +Workspace::Private::RestoreConfiguration(const BMessage& settings) { + rgb_color color; + if (settings.FindInt32("color", (int32 *)&color) == B_OK) + fColor.SetColor(color); } void -Workspace::Private::GetSettings(BMessage& settings) +Workspace::Private::StoreConfiguration(BMessage& settings) { + rgb_color color = fColor.GetColor32(); + settings.AddInt32("color", *(int32 *)&color); } diff --git a/src/servers/app/WorkspacePrivate.h b/src/servers/app/WorkspacePrivate.h index 5d7e7ddbd9..be2c9d27f0 100644 --- a/src/servers/app/WorkspacePrivate.h +++ b/src/servers/app/WorkspacePrivate.h @@ -45,8 +45,8 @@ class Workspace::Private { const RGBColor& Color() const { return fColor; } void SetColor(const RGBColor& color); - void SetSettings(BMessage& settings); - void GetSettings(BMessage& settings); + void RestoreConfiguration(const BMessage& settings); + void StoreConfiguration(BMessage& settings); private: void _SetDefaults();