1 /* 2 * Copyright 2005-2006, Haiku. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Axel Dörfler, axeld@pinc-software.de 7 */ 8 9 10 #include "VirtualScreen.h" 11 12 #include "HWInterface.h" 13 #include "Desktop.h" 14 15 #include <new> 16 17 using std::nothrow; 18 19 20 VirtualScreen::VirtualScreen() 21 : 22 fScreenList(4, true), 23 fDrawingEngine(NULL), 24 fHWInterface(NULL) 25 { 26 } 27 28 29 VirtualScreen::~VirtualScreen() 30 { 31 _Reset(); 32 } 33 34 35 void 36 VirtualScreen::_Reset() 37 { 38 ScreenList list; 39 for (int32 i = 0; i < fScreenList.CountItems(); i++) { 40 screen_item* item = fScreenList.ItemAt(i); 41 42 list.AddItem(item->screen); 43 } 44 45 gScreenManager->ReleaseScreens(list); 46 fScreenList.MakeEmpty(); 47 fSettings.MakeEmpty(); 48 49 fFrame.Set(0, 0, 0, 0); 50 fDrawingEngine = NULL; 51 fHWInterface = NULL; 52 } 53 54 55 status_t 56 VirtualScreen::RestoreConfiguration(Desktop& desktop, const BMessage* settings) 57 { 58 _Reset(); 59 60 // Copy current Desktop workspace settings 61 if (settings) 62 fSettings = *settings; 63 64 ScreenList list; 65 status_t status = gScreenManager->AcquireScreens(&desktop, NULL, 0, false, list); 66 if (status < B_OK) { 67 // TODO: we would try again here with force == true 68 return status; 69 } 70 71 for (int32 i = 0; i < list.CountItems(); i++) { 72 Screen* screen = list.ItemAt(i); 73 74 AddScreen(screen); 75 } 76 77 return B_OK; 78 } 79 80 81 status_t 82 VirtualScreen::StoreConfiguration(BMessage& settings) 83 { 84 for (int32 i = 0; i < fScreenList.CountItems(); i++) { 85 screen_item* item = fScreenList.ItemAt(i); 86 Screen* screen = item->screen; 87 if (!screen->IsDefaultMode()) 88 continue; 89 90 BMessage screenSettings; 91 screenSettings.AddInt32("id", screen->ID()); 92 //screenSettings.AddString("name", "-"); 93 screenSettings.AddRect("frame", item->frame); 94 95 // TODO: or just store a display_mode completely? 96 uint16 width, height; 97 uint32 colorSpace; 98 float frequency; 99 screen->GetMode(width, height, colorSpace, frequency); 100 101 screenSettings.AddInt32("width", width); 102 screenSettings.AddInt32("height", height); 103 screenSettings.AddInt32("color space", colorSpace); 104 screenSettings.AddFloat("frequency", frequency); 105 106 settings.AddMessage("screen", &screenSettings); 107 } 108 109 return B_OK; 110 } 111 112 113 status_t 114 VirtualScreen::AddScreen(Screen* screen) 115 { 116 screen_item* item = new(nothrow) screen_item; 117 if (item == NULL) 118 return B_NO_MEMORY; 119 120 item->screen = screen; 121 122 status_t status = B_ERROR; 123 BMessage settings; 124 if (_FindConfiguration(screen, settings) == B_OK) { 125 // we found settings for this screen, and try to apply them now 126 int32 width, height, colorSpace; 127 float frequency; 128 if (settings.FindInt32("width", &width) == B_OK 129 && settings.FindInt32("height", &height) == B_OK 130 && settings.FindInt32("color space", &colorSpace) == B_OK 131 && settings.FindFloat("frequency", &frequency) == B_OK) 132 status = screen->SetMode(width, height, colorSpace, frequency, true); 133 } 134 if (status < B_OK) { 135 // TODO: more intelligent standard mode (monitor preference, desktop default, ...) 136 screen->SetMode(800, 600, B_RGB32, 60.f, false); 137 } 138 139 // TODO: this works only for single screen configurations 140 fDrawingEngine = screen->GetDrawingEngine(); 141 fHWInterface = screen->HWInterface(); 142 fFrame = screen->Frame(); 143 144 fScreenList.AddItem(item); 145 146 return B_OK; 147 } 148 149 150 status_t 151 VirtualScreen::RemoveScreen(Screen* screen) 152 { 153 // not implemented yet (config changes when running) 154 return B_ERROR; 155 } 156 157 158 /*! 159 Returns the smallest frame that spans over all screens 160 */ 161 BRect 162 VirtualScreen::Frame() const 163 { 164 return fFrame; 165 } 166 167 168 Screen* 169 VirtualScreen::ScreenAt(int32 index) const 170 { 171 screen_item* item = fScreenList.ItemAt(index); 172 if (item != NULL) 173 return item->screen; 174 175 return NULL; 176 } 177 178 179 BRect 180 VirtualScreen::ScreenFrameAt(int32 index) const 181 { 182 screen_item* item = fScreenList.ItemAt(index); 183 if (item != NULL) 184 return item->frame; 185 186 return BRect(0, 0, 0, 0); 187 } 188 189 190 int32 191 VirtualScreen::CountScreens() const 192 { 193 return fScreenList.CountItems(); 194 } 195 196 197 status_t 198 VirtualScreen::_FindConfiguration(Screen* screen, BMessage& settings) 199 { 200 // TODO: we probably want to identify the resolution by connected monitor, 201 // and not the display driver used... 202 // For now, we just use the screen ID, which is almost nothing, anyway... 203 204 uint32 i = 0; 205 while (fSettings.FindMessage("screen", i++, &settings) == B_OK) { 206 int32 id; 207 if (settings.FindInt32("id", &id) != B_OK 208 || screen->ID() != id) 209 continue; 210 211 // we found our match 212 return B_OK; 213 } 214 215 return B_NAME_NOT_FOUND; 216 } 217 218