1 /* 2 * Copyright 2005, 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 #include "ServerScreen.h" 14 15 #include <Autolock.h> 16 #include <Entry.h> 17 #include <NodeMonitor.h> 18 19 #include <new> 20 21 22 #ifdef __HAIKU__ 23 # define USE_ACCELERANT 1 24 #else 25 # define USE_ACCELERANT 0 26 #endif 27 28 #if USE_ACCELERANT 29 # include "AccelerantHWInterface.h" 30 #else 31 # include "ViewHWInterface.h" 32 #endif 33 34 35 ScreenManager* gScreenManager; 36 37 38 ScreenManager::ScreenManager() 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 #if USE_ACCELERANT 143 interface = new AccelerantHWInterface(); 144 #else 145 interface = new ViewHWInterface(); 146 #endif 147 148 _AddHWInterface(interface); 149 initDrivers = false; 150 } 151 } 152 153 154 void 155 ScreenManager::_AddHWInterface(HWInterface* interface) 156 { 157 Screen* screen = new(nothrow) Screen(interface, fScreenList.CountItems() + 1); 158 if (screen == NULL) { 159 delete interface; 160 return; 161 } 162 163 // The interface is now owned by the screen 164 165 if (screen->Initialize() >= B_OK) { 166 screen_item* item = new(nothrow) screen_item; 167 if (item != NULL) { 168 item->screen = screen; 169 item->owner = NULL; 170 if (fScreenList.AddItem(item)) 171 return; 172 173 delete item; 174 } 175 } 176 177 delete screen; 178 } 179 180 181 void 182 ScreenManager::MessageReceived(BMessage* message) 183 { 184 switch (message->what) { 185 case B_NODE_MONITOR: 186 // ToDo: handle notification 187 break; 188 189 default: 190 BHandler::MessageReceived(message); 191 } 192 } 193 194