1 /* 2 * Copyright 2005-2009, Haiku. 3 * Distributed under the terms of the MIT License. 4 * 5 * Authors: 6 * Axel Dörfler, axeld@pinc-software.de 7 */ 8 9 /** Manages all available physical screens */ 10 11 12 #include "ScreenManager.h" 13 14 #include "Screen.h" 15 #include "ServerConfig.h" 16 17 #include "remote/RemoteHWInterface.h" 18 19 #include <Autolock.h> 20 #include <Entry.h> 21 #include <NodeMonitor.h> 22 23 #include <new> 24 25 using std::nothrow; 26 27 28 #ifndef HAIKU_TARGET_PLATFORM_LIBBE_TEST 29 # include "AccelerantHWInterface.h" 30 #else 31 # include "ViewHWInterface.h" 32 # include "DWindowHWInterface.h" 33 #endif 34 35 36 ScreenManager* gScreenManager; 37 38 39 ScreenManager::ScreenManager() 40 : 41 BLooper("screen manager"), 42 fScreenList(4) 43 { 44 _ScanDrivers(); 45 46 // turn on node monitoring the graphics driver directory 47 BEntry entry("/dev/graphics"); 48 node_ref nodeRef; 49 if (entry.InitCheck() == B_OK && entry.GetNodeRef(&nodeRef) == B_OK) 50 watch_node(&nodeRef, B_WATCH_DIRECTORY, this); 51 } 52 53 54 ScreenManager::~ScreenManager() 55 { 56 for (int32 i = 0; i < fScreenList.CountItems(); i++) { 57 screen_item* item = fScreenList.ItemAt(i); 58 59 delete item->screen; 60 delete item; 61 } 62 } 63 64 65 Screen* 66 ScreenManager::ScreenAt(int32 index) const 67 { 68 if (!IsLocked()) 69 debugger("Called ScreenManager::ScreenAt() without lock!"); 70 71 screen_item* item = fScreenList.ItemAt(index); 72 if (item != NULL) 73 return item->screen; 74 75 return NULL; 76 } 77 78 79 int32 80 ScreenManager::CountScreens() const 81 { 82 if (!IsLocked()) 83 debugger("Called ScreenManager::CountScreens() without lock!"); 84 85 return fScreenList.CountItems(); 86 } 87 88 89 status_t 90 ScreenManager::AcquireScreens(ScreenOwner* owner, int32* wishList, 91 int32 wishCount, const char* target, bool force, ScreenList& list) 92 { 93 BAutolock locker(this); 94 int32 added = 0; 95 96 // TODO: don't ignore the wish list 97 98 for (int32 i = 0; i < fScreenList.CountItems(); i++) { 99 screen_item* item = fScreenList.ItemAt(i); 100 101 if (item->owner == NULL && list.AddItem(item->screen)) { 102 item->owner = owner; 103 added++; 104 } 105 } 106 107 #if TEST_MODE == 0 108 if (added == 0 && target != NULL) { 109 // there's a specific target screen we want to initialize 110 // TODO: right now we only support remote screens, but we could 111 // also target specific accelerants to support other graphics cards 112 RemoteHWInterface* interface = new(nothrow) RemoteHWInterface(target); 113 if (interface != NULL) { 114 screen_item* item = _AddHWInterface(interface); 115 if (item != NULL && list.AddItem(item->screen)) { 116 item->owner = owner; 117 added++; 118 } 119 } 120 } 121 #endif // TEST_MODE == 0 122 123 return added > 0 ? B_OK : B_ENTRY_NOT_FOUND; 124 } 125 126 127 void 128 ScreenManager::ReleaseScreens(ScreenList& list) 129 { 130 BAutolock locker(this); 131 132 for (int32 i = 0; i < fScreenList.CountItems(); i++) { 133 screen_item* item = fScreenList.ItemAt(i); 134 135 for (int32 j = 0; j < list.CountItems(); j++) { 136 Screen* screen = list.ItemAt(j); 137 138 if (item->screen == screen) 139 item->owner = NULL; 140 } 141 } 142 } 143 144 145 void 146 ScreenManager::_ScanDrivers() 147 { 148 HWInterface* interface = NULL; 149 150 // Eventually we will loop through drivers until 151 // one can't initialize in order to support multiple monitors. 152 // For now, we'll just load one and be done with it. 153 154 // ToDo: to make monitoring the driver directory useful, we need more 155 // power and data here, and should do the scanning on our own 156 157 bool initDrivers = true; 158 while (initDrivers) { 159 160 #ifndef HAIKU_TARGET_PLATFORM_LIBBE_TEST 161 interface = new AccelerantHWInterface(); 162 #elif defined(USE_DIRECT_WINDOW_TEST_MODE) 163 interface = new DWindowHWInterface(); 164 #else 165 interface = new ViewHWInterface(); 166 #endif 167 168 _AddHWInterface(interface); 169 initDrivers = false; 170 } 171 } 172 173 174 ScreenManager::screen_item* 175 ScreenManager::_AddHWInterface(HWInterface* interface) 176 { 177 Screen* screen = new(nothrow) Screen(interface, fScreenList.CountItems()); 178 if (screen == NULL) { 179 delete interface; 180 return NULL; 181 } 182 183 // The interface is now owned by the screen 184 185 if (screen->Initialize() >= B_OK) { 186 screen_item* item = new(nothrow) screen_item; 187 if (item != NULL) { 188 item->screen = screen; 189 item->owner = NULL; 190 if (fScreenList.AddItem(item)) 191 return item; 192 193 delete item; 194 } 195 } 196 197 delete screen; 198 return NULL; 199 } 200 201 202 void 203 ScreenManager::MessageReceived(BMessage* message) 204 { 205 switch (message->what) { 206 case B_NODE_MONITOR: 207 // TODO: handle notification 208 break; 209 210 default: 211 BHandler::MessageReceived(message); 212 } 213 } 214 215