From fd5bec1e482fc3aa3b6b98ae26599433d3cb797d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Fri, 15 Jul 2005 12:45:23 +0000 Subject: [PATCH] First baby step to a restructured app_server: - introduced new ScreenManager and VirtualScreen classes - removed screen handling from RootLayer - removed multiple screen/root layer stuff from Desktop, it's now using a VirtualScreen object instead git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@13686 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/servers/app/AppServer.cpp | 3 + src/servers/app/Desktop.cpp | 127 ++------------------ src/servers/app/Desktop.h | 58 +++------ src/servers/app/Jamfile | 5 +- src/servers/app/RootLayer.cpp | 122 ++----------------- src/servers/app/RootLayer.h | 17 --- src/servers/app/ScreenManager.cpp | 193 ++++++++++++++++++++++++++++++ src/servers/app/ScreenManager.h | 62 ++++++++++ src/servers/app/ServerScreen.cpp | 11 +- src/servers/app/ServerScreen.h | 3 +- src/servers/app/VirtualScreen.cpp | 146 ++++++++++++++++++++++ src/servers/app/VirtualScreen.h | 66 ++++++++++ 12 files changed, 524 insertions(+), 289 deletions(-) create mode 100644 src/servers/app/ScreenManager.cpp create mode 100644 src/servers/app/ScreenManager.h create mode 100644 src/servers/app/VirtualScreen.cpp create mode 100644 src/servers/app/VirtualScreen.h diff --git a/src/servers/app/AppServer.cpp b/src/servers/app/AppServer.cpp index 8ff74a94aa..fb346bc1d0 100644 --- a/src/servers/app/AppServer.cpp +++ b/src/servers/app/AppServer.cpp @@ -31,6 +31,7 @@ #include "RegistrarDefs.h" #include "RGBColor.h" #include "RootLayer.h" +#include "ScreenManager.h" #include "ServerApp.h" #include "ServerCursor.h" #include "ServerProtocol.h" @@ -165,6 +166,8 @@ AppServer::AppServer() : if (LoadColorSet(SERVER_SETTINGS_DIR COLOR_SETTINGS_NAME, &gGUIColorSet) != B_OK) gGUIColorSet.SetToDefaults(); + gScreenManager = new ScreenManager(); + // Set up the Desktop gDesktop = new Desktop(); gDesktop->Init(); diff --git a/src/servers/app/Desktop.cpp b/src/servers/app/Desktop.cpp index 6f84dc7b91..ed7a42eb1f 100644 --- a/src/servers/app/Desktop.cpp +++ b/src/servers/app/Desktop.cpp @@ -56,9 +56,6 @@ Desktop::Desktop() : fWinBorderList(64), - fRootLayerList(2), - fActiveRootLayer(NULL), - fScreenList(2), fActiveScreen(NULL), fMouseMode(B_NORMAL_MOUSE), fFFMouseMode(false) @@ -88,104 +85,24 @@ Desktop::~Desktop() for (int32 i = 0; WinBorder *border = (WinBorder *)fWinBorderList.ItemAt(i); i++) delete border; - for (int32 i = 0; RootLayer *rootLayer = (RootLayer *)fRootLayerList.ItemAt(i); i++) - delete rootLayer; - - for (int32 i = 0; Screen *screen = (Screen *)fScreenList.ItemAt(i); i++) - delete screen; + delete fRootLayer; } void Desktop::Init() { - HWInterface *interface = NULL; + fVirtualScreen.RestoreConfiguration(*this); - // 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. - - bool initDrivers = true; - while (initDrivers) { + // TODO: temporary workaround, fActiveScreen will be removed + fActiveScreen = fVirtualScreen.ScreenAt(0); -#if USE_ACCELERANT - interface = new AccelerantHWInterface(); -#else - interface = new ViewHWInterface(); -#endif + // TODO: add user identity to the name + char name[32]; + sprintf(name, "RootLayer %d", 1); - _AddGraphicsCard(interface); - initDrivers = false; - } - - if (fScreenList.CountItems() < 1) { - delete this; - return; - } - - InitMode(); - - SetActiveRootLayerByIndex(0); -} - - -void -Desktop::_AddGraphicsCard(HWInterface* interface) -{ - Screen *screen = new Screen(interface, fScreenList.CountItems() + 1); - // The interface is now owned by the screen - - if (screen->Initialize() >= B_OK && fScreenList.AddItem((void*)screen)) { - // TODO: be careful of screen initialization - monitor may not support 640x480 - screen->SetMode(800, 600, B_RGB32, 60.f); - } else - delete screen; -} - - -void -Desktop::InitMode() -{ - // this is init mode for n-SS. - fActiveScreen = (Screen *)fScreenList.ItemAt(0); - - for (int32 i = 0; i < fScreenList.CountItems(); i++) { - Screen *screen = (Screen *)fScreenList.ItemAt(i); - - char name[32]; - sprintf(name, "RootLayer %ld", i + 1); - - RootLayer *rootLayer = new RootLayer(name, 4, this, GetDisplayDriver()); - rootLayer->SetScreens(&screen, 1, 1); - rootLayer->RunThread(); - - fRootLayerList.AddItem(rootLayer); - } -} - - -//--------------------------------------------------------------------------- -// Methods for multiple monitors. -//--------------------------------------------------------------------------- - - -inline void -Desktop::SetActiveRootLayerByIndex(int32 listIndex) -{ - RootLayer *rootLayer = RootLayerAt(listIndex); - - if (rootLayer != NULL) - SetActiveRootLayer(rootLayer); -} - - -inline void -Desktop::SetActiveRootLayer(RootLayer *rootLayer) -{ - if (fActiveRootLayer == rootLayer) - return; - - fActiveRootLayer = rootLayer; + fRootLayer = new RootLayer(name, 4, this, GetDisplayDriver()); + fRootLayer->RunThread(); } @@ -541,29 +458,3 @@ Desktop::FFMouseMode(void) const return fMouseMode; } - -void -Desktop::PrintToStream(void) -{ - printf("RootLayer List:\n=======\n"); - - for (int32 i = 0; i < fRootLayerList.CountItems(); i++) { - printf("\t%s\n", ((RootLayer*)fRootLayerList.ItemAt(i))->Name()); - ((RootLayer*)fRootLayerList.ItemAt(i))->PrintToStream(); - printf("-------\n"); - } - - printf("=======\nActive RootLayer: %s\n", - fActiveRootLayer ? fActiveRootLayer->Name() : "NULL"); -// printf("Active WinBorder: %s\n", fActiveWinBorder? fActiveWinBorder->Name(): "NULL"); - - printf("Screen List:\n"); - for (int32 i = 0; i < fScreenList.CountItems(); i++) - printf("\t%ld\n", ((Screen*)fScreenList.ItemAt(i))->ScreenNumber()); -} - - -void -Desktop::PrintVisibleInRootLayerNo(int32 no) -{ -} diff --git a/src/servers/app/Desktop.h b/src/servers/app/Desktop.h index dde8faaed2..4a583b4e62 100644 --- a/src/servers/app/Desktop.h +++ b/src/servers/app/Desktop.h @@ -11,13 +11,16 @@ #define _DESKTOP_H_ +#include "ScreenManager.h" +#include "ServerScreen.h" +#include "VirtualScreen.h" + #include #include #include #include #include -#include "ServerScreen.h" class BMessage; @@ -32,7 +35,7 @@ namespace BPrivate { }; -class Desktop : public BLocker { +class Desktop : public BLocker, public ScreenOwner { public: // startup methods Desktop(); @@ -40,41 +43,22 @@ class Desktop : public BLocker { void Init(); - // 1-BigScreen or n-SmallScreens - void InitMode(); - // Methods for multiple monitors. inline Screen* ScreenAt(int32 index) const - { return static_cast(fScreenList.ItemAt(index)); } - inline int32 ScreenCount() const - { return fScreenList.CountItems(); } + { return fActiveScreen; } inline Screen* ActiveScreen() const { return fActiveScreen; } + inline RootLayer* ActiveRootLayer() const { return fRootLayer; } - void SetActiveRootLayerByIndex(int32 index); - void SetActiveRootLayer(RootLayer* layer); - inline RootLayer* RootLayerAt(int32 index) - { return static_cast(fRootLayerList.ItemAt(index)); } - RootLayer* ActiveRootLayer() const - { return fActiveRootLayer;} - int32 ActiveRootLayerIndex() const - { - int32 rootLayerCount = CountRootLayers(); - - for (int32 i = 0; i < rootLayerCount; i++) { - if (fActiveRootLayer == (RootLayer *)fRootLayerList.ItemAt(i)) - return i; - } - return -1; - } - - inline int32 CountRootLayers() const - { return fRootLayerList.CountItems(); } + virtual void ScreenRemoved(Screen* screen) {} + virtual void ScreenAdded(Screen* screen) {} + virtual bool ReleaseScreen(Screen* screen) { return false; } + const ::VirtualScreen& VirtualScreen() const { return fVirtualScreen; } inline DisplayDriver* GetDisplayDriver() const - { return ScreenAt(0)->GetDisplayDriver(); } + { return fVirtualScreen.DisplayDriver(); } inline HWInterface* GetHWInterface() const - { return ScreenAt(0)->GetHWInterface(); } + { return fVirtualScreen.HWInterface(); } // Methods for layer(WinBorder) manipulation. void AddWinBorder(WinBorder *winBorder); @@ -112,21 +96,13 @@ class Desktop : public BLocker { void SetFFMouseMode(const mode_mouse &value); mode_mouse FFMouseMode() const; - // Debugging methods - void PrintToStream(); - void PrintVisibleInRootLayerNo(int32 no); - private: - void _AddGraphicsCard(HWInterface* interface); - + ::VirtualScreen fVirtualScreen; BList fWinBorderList; - - BList fRootLayerList; - RootLayer* fActiveRootLayer; - - BList fScreenList; + + RootLayer* fRootLayer; Screen* fActiveScreen; - + scroll_bar_info fScrollBarInfo; menu_info fMenuInfo; mode_mouse fMouseMode; diff --git a/src/servers/app/Jamfile b/src/servers/app/Jamfile index 657b031fae..4063acbde5 100644 --- a/src/servers/app/Jamfile +++ b/src/servers/app/Jamfile @@ -3,7 +3,8 @@ SubDir OBOS_TOP src servers app ; AddResources app_server : app_server.rdef ; UseLibraryHeaders agg png zlib ; -UsePrivateHeaders app interface [ FDirName servers app ] ; +UsePrivateHeaders app interface shared [ FDirName servers app ] ; + UseHeaders [ FDirName $(OBOS_TOP) src servers app drawing ] ; UseHeaders [ FDirName $(OBOS_TOP) src servers app drawing Painter ] ; UseHeaders [ FDirName $(OBOS_TOP) src servers app drawing Painter drawing_modes ] ; @@ -83,10 +84,12 @@ Server app_server : ServerApp.cpp ServerWindow.cpp DecorManager.cpp + ScreenManager.cpp # DisplayDriver Classes $(VIEW_DRIVER_SOURCES) + VirtualScreen.cpp BBitmapBuffer.cpp BitmapHWInterface.cpp DefaultDecorator.cpp diff --git a/src/servers/app/RootLayer.cpp b/src/servers/app/RootLayer.cpp index bd7be19ddb..818c78186c 100644 --- a/src/servers/app/RootLayer.cpp +++ b/src/servers/app/RootLayer.cpp @@ -88,15 +88,6 @@ RootLayer::RootLayer(const char *name, int32 workspaceCount, fThreadID(B_ERROR), fListenPort(-1), - fScreenPtrList(32), - fRows(0), - fColumns(0), - - fScreenWidth(0), - fScreenHeight(0), - fColorSpace(B_RGB32), - fFrequency(60.0), - fButtons(0), fLastMousePosition(0.0, 0.0), // fMovingWindow(false), @@ -172,6 +163,8 @@ RootLayer::RootLayer(const char *name, int32 workspaceCount, #if ON_SCREEN_DEBUGGING_INFO DebugInfoManager::Default()->SetRootLayer(this); #endif + + fFrame = desktop->VirtualScreen().Frame(); } @@ -1026,73 +1019,6 @@ RootLayer::WinBorderAt(const BPoint& pt) const } -void -RootLayer::SetScreens(Screen *screens[], int32 rows, int32 columns) -{ - // NOTE: All screens *must* have the same resolution - - // TODO: This function is badly named. Appearently, it - // adjusts the root layers frame rectangle, taking the information - // from the first screen in its list. However, a Screen object - // has actually now a different meaning. It manages access to - // the hardware and *owns* the HWInterface instance. - // This means there is going to be one Screen object per physical - // screen attached (unless I misunderstood how it was intended). - // A workspace needs to be attached to a screen - // and then on workspace activation, the appropriate updating - // needs to occur. The workspace tells its screen to configure - // to the workspaces mode, and then someone takes care of - // telling RootLayer to adjust itself and all other layers regions. - - uint16 width, height; - uint32 colorSpace; - float frequency; - screens[0]->GetMode(width, height, colorSpace, frequency); - - fFrame.Set(0, 0, width * columns - 1, height * rows - 1); - fRows = rows; - fColumns = columns; - fScreenWidth = width; - fScreenHeight = height; -} - - -Screen ** -RootLayer::Screens() -{ - return (Screen**)fScreenPtrList.Items(); -} - - -bool -RootLayer::SetScreenMode(int32 width, int32 height, uint32 colorSpace, float frequency) -{ - if (fScreenWidth == width && fScreenHeight == height - && fColorSpace == colorSpace && frequency == fFrequency) - return true; - - // NOTE: Currently, we have only one screen in that list. - // Before I changed it, this function would only accept modes - // that each of the (potentially multiple) screens can accept. - // However, I didn't really know what this gives in practice. - // We should re-think this when we really do support multiple monitors. - // For now, this function could potentially set the first couple of - // screens to the new mode, and fail to do so for the rest of them. - - status_t ret = B_ERROR; - for (int i = 0; i < fScreenPtrList.CountItems(); i++) { - Screen *screen = static_cast(fScreenPtrList.ItemAt(i)); - - ret = screen->SetMode(width, height, colorSpace, frequency); - if (ret < B_OK) - break; - } - - SetScreens(Screens(), fRows, fColumns); - - return ret >= B_OK; -} - //--------------------------------------------------------------------------- // Workspace related methods //--------------------------------------------------------------------------- @@ -1825,17 +1751,14 @@ RootLayer::SetEventMaskLayer(Layer *lay, uint32 mask, uint32 options) if (!lay) return false; - bool returnValue = true; + bool returnValue = true; Lock(); - if (fEventMaskLayer && fEventMaskLayer != lay) - { + if (fEventMaskLayer && fEventMaskLayer != lay) { fprintf(stderr, "WARNING: fEventMaskLayer already set and different than the required one!\n"); returnValue = false; - } - else - { + } else { fEventMaskLayer = lay; // TODO: use this mask and options! } @@ -1849,22 +1772,21 @@ RootLayer::SetEventMaskLayer(Layer *lay, uint32 mask, uint32 options) void RootLayer::LayerRemoved(Layer* layer) { - if (layer == fEventMaskLayer) { + if (layer == fEventMaskLayer) fEventMaskLayer = NULL; - } - if (layer == fLastMouseMoved) { + + if (layer == fLastMouseMoved) fLastMouseMoved = NULL; - } - if (layer == fMouseTargetWinBorder) { + + if (layer == fMouseTargetWinBorder) fMouseTargetWinBorder = NULL; - } } + void RootLayer::SetDragMessage(BMessage* msg) { - if (fDragMessage) - { + if (fDragMessage) { delete fDragMessage; fDragMessage = NULL; } @@ -1880,26 +1802,6 @@ RootLayer::DragMessage(void) const return fDragMessage; } -// DEBUG methods - -void -RootLayer::PrintToStream() -{ - printf("\nRootLayer '%s' internals:\n", Name()); - printf("Screen list:\n"); - for(int32 i=0; iScreenNumber()); - - printf("Screen rows: %ld\nScreen columns: %ld\n", fRows, fColumns); - printf("Resolution for all Screens: %ldx%ldx%ld\n", fScreenWidth, fScreenHeight, fColorSpace); - printf("Workspace list:\n"); - for(int32 i=0; iID()); - ((Workspace*)fWorkspace[i])->PrintToStream(); - printf("~~~~~~~~\n"); - } -} // PRIVATE methods diff --git a/src/servers/app/RootLayer.h b/src/servers/app/RootLayer.h index a9383ee1c2..60e20b4e62 100644 --- a/src/servers/app/RootLayer.h +++ b/src/servers/app/RootLayer.h @@ -106,12 +106,6 @@ public: void SetWorkspacesLayer(Layer* layer) { fWorkspacesLayer = layer; } Layer* WorkspacesLayer() const { return fWorkspacesLayer; } - void SetScreens(Screen *screen[], int32 rows, int32 columns); - Screen** Screens(void); - bool SetScreenMode(int32 width, int32 height, uint32 colorspace, float frequency); - int32 ScreenRows(void) const { return fRows; } - int32 ScreenColumns(void) const { return fColumns; } - void SetBGColor(const RGBColor &col); RGBColor BGColor(void) const; @@ -141,8 +135,6 @@ public: virtual void Draw(const BRect &r); - // Debug methods - void PrintToStream(void); thread_id LockingThread() { return fAllRegionsLock.LockingThread(); } BRegion fRedrawReg; @@ -195,15 +187,6 @@ friend class Desktop; thread_id fThreadID; port_id fListenPort; - BList fScreenPtrList; - int32 fRows; - int32 fColumns; - - int32 fScreenWidth; - int32 fScreenHeight; - uint32 fColorSpace; - float fFrequency; - int32 fButtons; BPoint fLastMousePosition; bool fMovingWindow; diff --git a/src/servers/app/ScreenManager.cpp b/src/servers/app/ScreenManager.cpp new file mode 100644 index 0000000000..2bfbb35e67 --- /dev/null +++ b/src/servers/app/ScreenManager.cpp @@ -0,0 +1,193 @@ +/* + * 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 + + +#ifdef __HAIKU__ +# define USE_ACCELERANT 1 +#else +# define USE_ACCELERANT 0 +#endif + +#if USE_ACCELERANT +# include "AccelerantHWInterface.h" +#else +# include "ViewHWInterface.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(); i++) { + 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) { + +#if USE_ACCELERANT + interface = new AccelerantHWInterface(); +#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); + } +} + diff --git a/src/servers/app/ScreenManager.h b/src/servers/app/ScreenManager.h new file mode 100644 index 0000000000..6cf714f8f2 --- /dev/null +++ b/src/servers/app/ScreenManager.h @@ -0,0 +1,62 @@ +/* + * Copyright 2005, Haiku. + * Distributed under the terms of the MIT License. + * + * Authors: + * Axel Dörfler, axeld@pinc-software.de + */ +#ifndef SCREEN_MANAGER_H +#define SCREEN_MANAGER_H + + +#include +#include + +class BMessage; + +class DisplayDriver; +class HWInterface; +class Screen; + + +typedef BObjectList ScreenList; + + +class ScreenOwner { + public: + virtual void ScreenRemoved(Screen* screen) = 0; + virtual void ScreenAdded(Screen* screen) = 0; + + virtual bool ReleaseScreen(Screen* screen) = 0; +}; + + +class ScreenManager : public BLooper { + public: + ScreenManager(); + virtual ~ScreenManager(); + + Screen* ScreenAt(int32 index) const; + int32 CountScreens() const; + + status_t AcquireScreens(ScreenOwner* owner, int32* wishList, + int32 wishCount, bool force, ScreenList& list); + void ReleaseScreens(ScreenList& list); + + virtual void MessageReceived(BMessage* message); + + private: + void _ScanDrivers(); + void _AddHWInterface(HWInterface* interface); + + struct screen_item { + Screen* screen; + ScreenOwner* owner; + }; + + BObjectList fScreenList; +}; + +extern ScreenManager *gScreenManager; + +#endif /* SCREEN_MANAGER_H */ diff --git a/src/servers/app/ServerScreen.cpp b/src/servers/app/ServerScreen.cpp index 735ce727e1..6374815126 100644 --- a/src/servers/app/ServerScreen.cpp +++ b/src/servers/app/ServerScreen.cpp @@ -130,7 +130,6 @@ Screen::GetMode(uint16 &width, uint16 &height, uint32 &colorspace, float &frequency) const { display_mode mode; - fHWInterface->GetMode(&mode); width = mode.virtual_width; @@ -141,6 +140,16 @@ Screen::GetMode(uint16 &width, uint16 &height, uint32 &colorspace, } +BRect +Screen::Frame() const +{ + display_mode mode; + fHWInterface->GetMode(&mode); + + return BRect(0, 0, mode.virtual_width - 1, mode.virtual_height - 1); +} + + status_t Screen::_FindMode(uint16 width, uint16 height, uint32 colorspace, float frequency, display_mode* mode) const diff --git a/src/servers/app/ServerScreen.h b/src/servers/app/ServerScreen.h index c07f85b976..d49d719d57 100644 --- a/src/servers/app/ServerScreen.h +++ b/src/servers/app/ServerScreen.h @@ -40,7 +40,8 @@ class Screen { uint16 &height, uint32 &colorspace, float &frequency) const; - + BRect Frame() const; + inline int32 ScreenNumber() const { return fID; } diff --git a/src/servers/app/VirtualScreen.cpp b/src/servers/app/VirtualScreen.cpp new file mode 100644 index 0000000000..5723df1096 --- /dev/null +++ b/src/servers/app/VirtualScreen.cpp @@ -0,0 +1,146 @@ +/* + * Copyright 2005, Haiku. + * Distributed under the terms of the MIT License. + * + * Authors: + * Axel Dörfler, axeld@pinc-software.de + */ + + +#include "VirtualScreen.h" + +#include +#include +#include + +#include + + +VirtualScreen::VirtualScreen() + : + fScreenList(4, true), + fDisplayDriver(NULL), + fHWInterface(NULL) +{ +} + + +VirtualScreen::~VirtualScreen() +{ +} + + +status_t +VirtualScreen::RestoreConfiguration(Desktop& desktop) +{ + // Copy current Desktop settings + //fSettings = desktop.Settings(); + + ScreenList list; + status_t status = gScreenManager->AcquireScreens(&desktop, NULL, 0, false, list); + if (status < B_OK) { + // TODO: we would try again here with force == true + return status; + } + + for (int32 i = 0; i < list.CountItems(); i++) { + Screen* screen = list.ItemAt(i); + + AddScreen(screen); + } + + return B_OK; +} + + +status_t +VirtualScreen::StoreConfiguration(BMessage& settings) +{ + // TODO: implement me + return B_OK; +} + + +status_t +VirtualScreen::AddScreen(Screen* screen) +{ + screen_item* item = new(nothrow) screen_item; + if (item == NULL) + return B_NO_MEMORY; + + item->screen = screen; + + BMessage settings; + if (_FindConfiguration(screen, settings) == B_OK) { + // TODO: read from settings! + } else { + // TODO: more intelligent standard mode (monitor preference, desktop default, ...) + screen->SetMode(800, 600, B_RGB32, 60.f); + } + + // TODO: this works only for single screen configurations + fDisplayDriver = screen->GetDisplayDriver(); + fHWInterface = screen->GetHWInterface(); + fFrame = screen->Frame(); + + fScreenList.AddItem(item); + + return B_OK; +} + + +status_t +VirtualScreen::RemoveScreen(Screen* screen) +{ + // not implemented yet (config changes when running) + return B_ERROR; +} + + +/*! + Returns the smallest frame that spans over all screens +*/ +BRect +VirtualScreen::Frame() const +{ + return fFrame; +} + + +Screen* +VirtualScreen::ScreenAt(int32 index) const +{ + screen_item* item = fScreenList.ItemAt(index); + if (item != NULL) + return item->screen; + + return NULL; +} + + +BRect +VirtualScreen::ScreenFrameAt(int32 index) const +{ + screen_item* item = fScreenList.ItemAt(index); + if (item != NULL) + return item->frame; + + return BRect(0, 0, 0, 0); +} + + +int32 +VirtualScreen::CountScreens() const +{ + return fScreenList.CountItems(); +} + + +status_t +VirtualScreen::_FindConfiguration(Screen* screen, BMessage& settings) +{ + // TODO: we probably want to identify the resolution by connected monitor, + // and not the display driver used... + return B_ERROR; +} + diff --git a/src/servers/app/VirtualScreen.h b/src/servers/app/VirtualScreen.h new file mode 100644 index 0000000000..1225a49b73 --- /dev/null +++ b/src/servers/app/VirtualScreen.h @@ -0,0 +1,66 @@ +/* + * Copyright 2005, Haiku. + * Distributed under the terms of the MIT License. + * + * Authors: + * Axel Dörfler, axeld@pinc-software.de + */ +#ifndef VIRTUAL_SCREEN_H +#define VIRTUAL_SCREEN_H + + +#include "ScreenManager.h" + +#include + +class Desktop; +class DisplayDriver; +class HWInterface; + + +class VirtualScreen { + public: + VirtualScreen(); + ~VirtualScreen(); + + ::DisplayDriver* DisplayDriver() const + { return fDisplayDriver; } + // TODO: can we have a multiplexing HWInterface as well? + // If not, this would need to be hidden, and only made + // available for the Screen class + ::HWInterface* HWInterface() const + { return fHWInterface; } + + status_t RestoreConfiguration(Desktop& desktop); + status_t StoreConfiguration(BMessage& settings); + + status_t AddScreen(Screen* screen); + status_t RemoveScreen(Screen* screen); + + BRect Frame() const; + + // TODO: we need to play with a real multi-screen configuration to + // figure out the specifics here - possibly in the test environment? + void SetScreenFrame(int32 index, BRect frame); + + Screen* ScreenAt(int32 index) const; + BRect ScreenFrameAt(int32 index) const; + int32 CountScreens() const; + + private: + status_t _FindConfiguration(Screen* screen, BMessage& settings); + + struct screen_item { + Screen* screen; + BRect frame; + // TODO: do we want to have a different color per screen as well? + }; + + BMessage fSettings; + BRect fFrame; + BObjectList fScreenList; + ::DisplayDriver* fDisplayDriver; + ::HWInterface* fHWInterface; +}; + +#endif /* VIRTUAL_SCREEN_H */