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#include "html5/HTML5HWInterface.h" 19 20#include <Autolock.h> 21#include <Entry.h> 22#include <NodeMonitor.h> 23 24#include <new> 25 26using 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 37ScreenManager* gScreenManager; 38 39 40ScreenManager::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 55ScreenManager::~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 66Screen* 67ScreenManager::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 80int32 81ScreenManager::CountScreens() const 82{ 83 if (!IsLocked()) 84 debugger("Called ScreenManager::CountScreens() without lock!"); 85 86 return fScreenList.CountItems(); 87} 88 89 90status_t 91ScreenManager::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 136void 137ScreenManager::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 154void 155ScreenManager::_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 183ScreenManager::screen_item* 184ScreenManager::_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 211void 212ScreenManager::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