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