status_t VirtualScreen::SetConfiguration(Desktop& desktop, ScreenConfigurations& configurations, uint32* _changedScreens) { // Remember previous screen modes typedef std::map<Screen*, display_mode> ScreenModeMap; ScreenModeMap previousModes; bool previousModesFailed = false; if (_changedScreens != NULL) { *_changedScreens = 0; try { for (int32 i = 0; i < fScreenList.CountItems(); i++) { Screen* screen = fScreenList.ItemAt(i)->screen; display_mode mode; screen->GetMode(mode); previousModes.insert(std::make_pair(screen, mode)); } } catch (...) { previousModesFailed = true; *_changedScreens = ~0L; } } _Reset(); ScreenList list; status_t status = gScreenManager->AcquireScreens(&desktop, NULL, 0, desktop.TargetScreen(), false, list); if (status != B_OK) { // TODO: we would try again here with force == true return status; } for (int32 i = 0; i < list.CountItems(); i++) { Screen* screen = list.ItemAt(i); AddScreen(screen, configurations); if (!previousModesFailed && _changedScreens != NULL) { // Figure out which screens have changed their mode display_mode mode; screen->GetMode(mode); ScreenModeMap::const_iterator found = previousModes.find(screen); if (found != previousModes.end() && memcmp(&mode, &found->second, sizeof(display_mode))) *_changedScreens |= 1 << i; } } UpdateFrame(); return B_OK; }
void VirtualScreen::UpdateFrame() { int32 virtualWidth = 0, virtualHeight = 0; for (int32 i = 0; i < fScreenList.CountItems(); i++) { Screen* screen = fScreenList.ItemAt(i)->screen; uint16 width, height; uint32 colorSpace; float frequency; screen->GetMode(width, height, colorSpace, frequency); // TODO: compute virtual size depending on the actual screen position! virtualWidth += width; virtualHeight = max_c(virtualHeight, height); } fFrame.Set(0, 0, virtualWidth - 1, virtualHeight - 1); }