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
This commit is contained in:
Axel Dörfler 2005-07-15 12:45:23 +00:00
parent 97021af901
commit fd5bec1e48
12 changed files with 524 additions and 289 deletions

View File

@ -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();

View File

@ -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)
{
}

View File

@ -11,13 +11,16 @@
#define _DESKTOP_H_
#include "ScreenManager.h"
#include "ServerScreen.h"
#include "VirtualScreen.h"
#include <InterfaceDefs.h>
#include <List.h>
#include <Locker.h>
#include <Menu.h>
#include <Autolock.h>
#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<Screen *>(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<RootLayer *>(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;

View File

@ -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

View File

@ -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<Screen *>(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; i<fScreenPtrList.CountItems(); i++)
printf("\t%ld\n", ((Screen*)fScreenPtrList.ItemAt(i))->ScreenNumber());
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; i<fWsCount; i++)
{
printf("\t~~~Workspace: %ld\n", ((Workspace*)fWorkspace[i])->ID());
((Workspace*)fWorkspace[i])->PrintToStream();
printf("~~~~~~~~\n");
}
}
// PRIVATE methods

View File

@ -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;

View File

@ -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 <Autolock.h>
#include <Entry.h>
#include <NodeMonitor.h>
#include <new>
#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);
}
}

View File

@ -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 <Looper.h>
#include <ObjectList.h>
class BMessage;
class DisplayDriver;
class HWInterface;
class Screen;
typedef BObjectList<Screen> 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<screen_item> fScreenList;
};
extern ScreenManager *gScreenManager;
#endif /* SCREEN_MANAGER_H */

View File

@ -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

View File

@ -40,7 +40,8 @@ class Screen {
uint16 &height,
uint32 &colorspace,
float &frequency) const;
BRect Frame() const;
inline int32 ScreenNumber() const
{ return fID; }

View File

@ -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 <DisplayDriver.h>
#include <HWInterface.h>
#include <Desktop.h>
#include <new>
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;
}

View File

@ -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 <Message.h>
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<screen_item> fScreenList;
::DisplayDriver* fDisplayDriver;
::HWInterface* fHWInterface;
};
#endif /* VIRTUAL_SCREEN_H */