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