From 4ee81443c3a220910aa7b7e654c8ce50fef6fa46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Fri, 19 Oct 2007 16:47:06 +0000 Subject: [PATCH] * The app_server now stores the whole display_timing structure of a mode, not just the frequency. * Previously saved modes are no longer supported, though. * Screen modes are now stored with the monitor info it belongs to, IOW the app_server will now choose a mode from the settings that fit your monitor description. Driver support is required for this to work as intended. * The changes are completely untested at this point, though, sorry (shouldn't harm anyone, though) :-) git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22622 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/servers/app/ServerScreen.cpp | 26 ++++++- src/servers/app/ServerScreen.h | 27 +++---- src/servers/app/VirtualScreen.cpp | 117 ++++++++++++++++++++++++------ src/servers/app/VirtualScreen.h | 6 +- 4 files changed, 136 insertions(+), 40 deletions(-) diff --git a/src/servers/app/ServerScreen.cpp b/src/servers/app/ServerScreen.cpp index 5b4053a44c..2d2b1c0a77 100644 --- a/src/servers/app/ServerScreen.cpp +++ b/src/servers/app/ServerScreen.cpp @@ -103,12 +103,27 @@ Screen::SetMode(const display_mode& mode, bool makeDefault) status_t -Screen::SetMode(uint16 width, uint16 height, uint32 colorspace, +Screen::SetMode(uint16 width, uint16 height, uint32 colorSpace, + const display_timing& timing, bool makeDefault) +{ + display_mode mode; + mode.virtual_width = width; + mode.virtual_height = height; + mode.space = colorSpace; + mode.timing = timing; + mode.flags = 0; + + return SetMode(mode, makeDefault); +} + + +status_t +Screen::SetMode(uint16 width, uint16 height, uint32 colorSpace, float frequency, bool makeDefault) { // search for a matching mode display_mode mode; - status_t status = _FindMode(width, height, colorspace, frequency, &mode); + status_t status = _FindMode(width, height, colorSpace, frequency, &mode); if (status < B_OK) return status; @@ -169,6 +184,13 @@ Screen::GetMode(uint16 &width, uint16 &height, uint32 &colorspace, } +status_t +Screen::GetMonitorInfo(monitor_info& info) const +{ + return fHWInterface->GetMonitorInfo(&info); +} + + BRect Screen::Frame() const { diff --git a/src/servers/app/ServerScreen.h b/src/servers/app/ServerScreen.h index 66f4ab659c..e152f3679c 100644 --- a/src/servers/app/ServerScreen.h +++ b/src/servers/app/ServerScreen.h @@ -29,19 +29,22 @@ class Screen { void Shutdown(); int32 ID() const { return fID; } - status_t GetMonitorInfo(monitor_info& info); + status_t GetMonitorInfo(monitor_info& info) const; - status_t SetMode(const display_mode& mode, bool makeDefault); + status_t SetMode(const display_mode& mode, + bool makeDefault); status_t SetMode(uint16 width, uint16 height, uint32 colorspace, float frequency, bool makeDefault); + status_t SetMode(uint16 width, uint16 height, + uint32 colorspace, + const display_timing& timing, + bool makeDefault); status_t SetPreferredMode(); void GetMode(display_mode* mode) const; - void GetMode(uint16 &width, - uint16 &height, - uint32 &colorspace, - float &frequency) const; + void GetMode(uint16 &width, uint16 &height, + uint32 &colorspace, float &frequency) const; BRect Frame() const; color_space ColorSpace() const; @@ -53,15 +56,13 @@ class Screen { { return fHWInterface; } private: - status_t _FindMode(uint16 width, - uint16 height, - uint32 colorspace, - float frequency, - display_mode* mode) const; + status_t _FindMode(uint16 width, uint16 height, + uint32 colorspace, float frequency, + display_mode* mode) const; int32 _FindMode(const display_mode* modeList, - uint32 count, uint16 width, uint16 height, - uint32 colorspace, float frequency) const; + uint32 count, uint16 width, uint16 height, + uint32 colorspace, float frequency) const; int32 fID; DrawingEngine* fDriver; diff --git a/src/servers/app/VirtualScreen.cpp b/src/servers/app/VirtualScreen.cpp index eb39ce516a..9b5b03e4c1 100644 --- a/src/servers/app/VirtualScreen.cpp +++ b/src/servers/app/VirtualScreen.cpp @@ -62,7 +62,8 @@ VirtualScreen::RestoreConfiguration(Desktop& desktop, const BMessage* settings) fSettings = *settings; ScreenList list; - status_t status = gScreenManager->AcquireScreens(&desktop, NULL, 0, false, list); + status_t status = gScreenManager->AcquireScreens(&desktop, NULL, 0, false, + list); if (status < B_OK) { // TODO: we would try again here with force == true return status; @@ -81,6 +82,8 @@ VirtualScreen::RestoreConfiguration(Desktop& desktop, const BMessage* settings) status_t VirtualScreen::StoreConfiguration(BMessage& settings) { + // store the configuration of all current screens + for (int32 i = 0; i < fScreenList.CountItems(); i++) { screen_item* item = fScreenList.ItemAt(i); Screen* screen = item->screen; @@ -89,23 +92,39 @@ VirtualScreen::StoreConfiguration(BMessage& settings) BMessage screenSettings; screenSettings.AddInt32("id", screen->ID()); - //screenSettings.AddString("name", "-"); + + monitor_info info; + if (screen->GetMonitorInfo(info) == B_OK) { + screenSettings.AddString("vendor", info.vendor); + screenSettings.AddString("name", info.name); + screenSettings.AddInt32("product id", info.product_id); + screenSettings.AddString("serial", info.serial_number); + screenSettings.AddInt32("produced week", info.produced.week); + screenSettings.AddInt32("produced year", info.produced.year); + } + 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); + display_mode mode; + screen->GetMode(&mode); - screenSettings.AddInt32("width", width); - screenSettings.AddInt32("height", height); - screenSettings.AddInt32("color space", colorSpace); - screenSettings.AddFloat("frequency", frequency); + screenSettings.AddInt32("width", mode.virtual_width); + screenSettings.AddInt32("height", mode.virtual_height); + screenSettings.AddInt32("color space", mode.space); + screenSettings.AddData("timing", B_RAW_TYPE, &mode.timing, + sizeof(display_timing)); settings.AddMessage("screen", &screenSettings); } + // store the configuration of all monitors currently not attached + + BMessage screenSettings; + for (uint32 i = 0; fSettings.FindMessage("screen", i, + &screenSettings) == B_OK; i++) { + settings.AddMessage("screen", &screenSettings); + } + return B_OK; } @@ -124,12 +143,15 @@ VirtualScreen::AddScreen(Screen* screen) if (_FindConfiguration(screen, settings) == B_OK) { // we found settings for this screen, and try to apply them now int32 width, height, colorSpace; - float frequency; + const display_timing* timing; + ssize_t size; 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); + && settings.FindData("timing", B_RAW_TYPE, (const void**)&timing, + &size) == B_OK + && size == sizeof(display_timing)) + status = screen->SetMode(width, height, colorSpace, *timing, true); } if (status < B_OK) { // TODO: more intelligent standard mode (monitor preference, desktop default, ...) @@ -220,18 +242,67 @@ VirtualScreen::CountScreens() const status_t VirtualScreen::_FindConfiguration(Screen* screen, BMessage& settings) { - // TODO: we probably want to identify the resolution by connected monitor, - // and not the display driver used... - // For now, we just use the screen ID, which is almost nothing, anyway... + monitor_info info; + bool hasInfo = screen->GetMonitorInfo(info) == B_OK; + if (!hasInfo) { + // only look for a matching ID - this is all we have + for (uint32 i = 0; fSettings.FindMessage("screen", i, + &settings) == B_OK; i++) { + int32 id; + if (settings.FindInt32("id", &id) != B_OK + || screen->ID() != id) + continue; - uint32 i = 0; - while (fSettings.FindMessage("screen", i++, &settings) == B_OK) { + // we found our match + fSettings.RemoveData("screen", i); + return B_OK; + } + } + + // look for a monitor configuration that matches ours + + int32 bestScore = 0; + int32 bestIndex = -1; + BMessage stored; + for (uint32 i = 0; fSettings.FindMessage("screen", i, &stored) == B_OK; + i++) { + int32 score = 0; int32 id; - if (settings.FindInt32("id", &id) != B_OK - || screen->ID() != id) - continue; + if (stored.FindInt32("id", &id) == B_OK && screen->ID() == id) + score++; - // we found our match + const char* vendor; + const char* name; + uint32 productID; + const char* serial; + int32 week, year; + if (stored.FindString("vendor", &vendor) == B_OK + && stored.FindString("name", &name) == B_OK + && stored.FindInt32("product id", (int32*)&productID) == B_OK + && stored.FindString("serial", &serial) == B_OK + && stored.FindInt32("produced week", &week) == B_OK + && stored.FindInt32("produced year", &year) == B_OK) { + if (!strcasecmp(vendor, info.vendor) + && !strcasecmp(name, info.name) + && productID == info.product_id) { + score += 2; + if (!strcmp(serial, info.serial_number)) + score += 2; + if (info.produced.year == year && info.produced.week == week) + score++; + } else + score -= 2; + } + + if (score > bestScore) { + settings = stored; + bestScore = score; + bestIndex = i; + } + } + + if (bestIndex >= 0) { + fSettings.RemoveData("screen", bestIndex); return B_OK; } diff --git a/src/servers/app/VirtualScreen.h b/src/servers/app/VirtualScreen.h index 1ff4b98ad0..5a61171b31 100644 --- a/src/servers/app/VirtualScreen.h +++ b/src/servers/app/VirtualScreen.h @@ -31,7 +31,8 @@ class VirtualScreen { ::HWInterface* HWInterface() const { return fHWInterface; } - status_t RestoreConfiguration(Desktop& desktop, const BMessage* settings); + status_t RestoreConfiguration(Desktop& desktop, + const BMessage* settings); status_t StoreConfiguration(BMessage& settings); status_t AddScreen(Screen* screen); @@ -49,7 +50,8 @@ class VirtualScreen { int32 CountScreens() const; private: - status_t _FindConfiguration(Screen* screen, BMessage& settings); + status_t _FindConfiguration(Screen* screen, + BMessage& settings); void _Reset(); struct screen_item {