/* * Copyright 2005, Haiku. * Distributed under the terms of the MIT License. * * Authors: * Axel Dörfler, axeld@pinc-software.de */ /** Manages all available physical screens */ #include "ScreenManager.h" #include "ServerScreen.h" #include #include #include #include using std::nothrow; #ifndef HAIKU_TARGET_PLATFORM_LIBBE_TEST # include "AccelerantHWInterface.h" #else # include "ViewHWInterface.h" # include "DWindowHWInterface.h" #endif ScreenManager* gScreenManager; ScreenManager::ScreenManager() : BLooper("screen manager"), fScreenList(4) { _ScanDrivers(); // turn on node monitoring the graphics driver directory BEntry entry("/dev/graphics"); node_ref nodeRef; if (entry.InitCheck() == B_OK && entry.GetNodeRef(&nodeRef) == B_OK) watch_node(&nodeRef, B_WATCH_DIRECTORY, this); } ScreenManager::~ScreenManager() { for (int32 i = 0; i < fScreenList.CountItems(); i++) { screen_item* item = fScreenList.ItemAt(i); delete item->screen; delete item; } } Screen* ScreenManager::ScreenAt(int32 index) const { if (!IsLocked()) debugger("Called ScreenManager::ScreenAt() without lock!"); screen_item* item = fScreenList.ItemAt(index); if (item != NULL) return item->screen; return NULL; } int32 ScreenManager::CountScreens() const { if (!IsLocked()) debugger("Called ScreenManager::CountScreens() without lock!"); return fScreenList.CountItems(); } status_t ScreenManager::AcquireScreens(ScreenOwner* owner, int32* wishList, int32 wishCount, bool force, ScreenList& list) { BAutolock locker(this); int32 added = 0; // ToDo: don't ignore the wish list for (int32 i = 0; i < fScreenList.CountItems(); i++) { screen_item *item = fScreenList.ItemAt(i); if (item->owner == NULL && list.AddItem(item->screen)) { item->owner = owner; added++; } } return added > 0 ? B_OK : B_ENTRY_NOT_FOUND; } void ScreenManager::ReleaseScreens(ScreenList& list) { BAutolock locker(this); for (int32 i = 0; i < fScreenList.CountItems(); i++) { screen_item *item = fScreenList.ItemAt(i); for (int32 j = 0; j < list.CountItems(); j++) { Screen* screen = list.ItemAt(j); if (item->screen == screen) item->owner = NULL; } } } void ScreenManager::_ScanDrivers() { HWInterface *interface = NULL; // Eventually we will loop through drivers until // one can't initialize in order to support multiple monitors. // For now, we'll just load one and be done with it. // ToDo: to make monitoring the driver directory useful, we need more // power and data here, and should do the scanning on our own bool initDrivers = true; while (initDrivers) { #ifndef HAIKU_TARGET_PLATFORM_LIBBE_TEST interface = new AccelerantHWInterface(); #elif defined(USE_DIRECT_WINDOW_TEST_MODE) interface = new DWindowHWInterface(); #else interface = new ViewHWInterface(); #endif _AddHWInterface(interface); initDrivers = false; } } void ScreenManager::_AddHWInterface(HWInterface* interface) { Screen* screen = new(nothrow) Screen(interface, fScreenList.CountItems() + 1); if (screen == NULL) { delete interface; return; } // The interface is now owned by the screen if (screen->Initialize() >= B_OK) { screen_item* item = new(nothrow) screen_item; if (item != NULL) { item->screen = screen; item->owner = NULL; if (fScreenList.AddItem(item)) return; delete item; } } delete screen; } void ScreenManager::MessageReceived(BMessage* message) { switch (message->what) { case B_NODE_MONITOR: // ToDo: handle notification break; default: BHandler::MessageReceived(message); } }