8527f8ffbe
modes right yet. The settings are stored in B_USER_SETTINGS_DIRECTORY/system/app_server/workspaces. They are currently saved as a flattened BMessage - we might want to switch to the driver_settings format, though. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@16249 a95241bf-73f2-0310-859d-f6bbb57e9c96
218 lines
4.3 KiB
C++
218 lines
4.3 KiB
C++
/*
|
|
* Copyright 2005-2006, Haiku.
|
|
* Distributed under the terms of the MIT License.
|
|
*
|
|
* Authors:
|
|
* Axel Dörfler, axeld@pinc-software.de
|
|
*/
|
|
|
|
|
|
#include "VirtualScreen.h"
|
|
|
|
#include "HWInterface.h"
|
|
#include "Desktop.h"
|
|
|
|
#include <new>
|
|
|
|
using std::nothrow;
|
|
|
|
|
|
VirtualScreen::VirtualScreen()
|
|
:
|
|
fScreenList(4, true),
|
|
fDrawingEngine(NULL),
|
|
fHWInterface(NULL)
|
|
{
|
|
}
|
|
|
|
|
|
VirtualScreen::~VirtualScreen()
|
|
{
|
|
_Reset();
|
|
}
|
|
|
|
|
|
void
|
|
VirtualScreen::_Reset()
|
|
{
|
|
ScreenList list;
|
|
for (int32 i = 0; i < fScreenList.CountItems(); i++) {
|
|
screen_item* item = fScreenList.ItemAt(i);
|
|
|
|
list.AddItem(item->screen);
|
|
}
|
|
|
|
gScreenManager->ReleaseScreens(list);
|
|
fScreenList.MakeEmpty();
|
|
fSettings.MakeEmpty();
|
|
|
|
fFrame.Set(0, 0, 0, 0);
|
|
fDrawingEngine = NULL;
|
|
fHWInterface = NULL;
|
|
}
|
|
|
|
|
|
status_t
|
|
VirtualScreen::RestoreConfiguration(Desktop& desktop, const BMessage* settings)
|
|
{
|
|
_Reset();
|
|
|
|
// Copy current Desktop workspace settings
|
|
if (settings)
|
|
fSettings = *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)
|
|
{
|
|
for (int32 i = 0; i < fScreenList.CountItems(); i++) {
|
|
screen_item* item = fScreenList.ItemAt(i);
|
|
Screen* screen = item->screen;
|
|
if (!screen->IsDefaultMode())
|
|
continue;
|
|
|
|
BMessage screenSettings;
|
|
screenSettings.AddInt32("id", screen->ID());
|
|
//screenSettings.AddString("name", "-");
|
|
screenSettings.AddRect("frame", item->frame);
|
|
|
|
// TODO: or just store a display_mode completely?
|
|
uint16 width, height;
|
|
uint32 colorSpace;
|
|
float frequency;
|
|
screen->GetMode(width, height, colorSpace, frequency);
|
|
|
|
screenSettings.AddInt32("width", width);
|
|
screenSettings.AddInt32("height", height);
|
|
screenSettings.AddInt32("color space", colorSpace);
|
|
screenSettings.AddFloat("frequency", frequency);
|
|
|
|
settings.AddMessage("screen", &screenSettings);
|
|
}
|
|
|
|
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;
|
|
|
|
status_t status = B_ERROR;
|
|
BMessage settings;
|
|
if (_FindConfiguration(screen, settings) == B_OK) {
|
|
// we found settings for this screen, and try to apply them now
|
|
int32 width, height, colorSpace;
|
|
float frequency;
|
|
if (settings.FindInt32("width", &width) == B_OK
|
|
&& settings.FindInt32("height", &height) == B_OK
|
|
&& settings.FindInt32("color space", &colorSpace) == B_OK
|
|
&& settings.FindFloat("frequency", &frequency) == B_OK)
|
|
status = screen->SetMode(width, height, colorSpace, frequency, true);
|
|
}
|
|
if (status < B_OK) {
|
|
// TODO: more intelligent standard mode (monitor preference, desktop default, ...)
|
|
screen->SetMode(800, 600, B_RGB32, 60.f, false);
|
|
}
|
|
|
|
// TODO: this works only for single screen configurations
|
|
fDrawingEngine = screen->GetDrawingEngine();
|
|
fHWInterface = screen->HWInterface();
|
|
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...
|
|
// For now, we just use the screen ID, which is almost nothing, anyway...
|
|
|
|
uint32 i = 0;
|
|
while (fSettings.FindMessage("screen", i++, &settings) == B_OK) {
|
|
int32 id;
|
|
if (settings.FindInt32("id", &id) != B_OK
|
|
|| screen->ID() != id)
|
|
continue;
|
|
|
|
// we found our match
|
|
return B_OK;
|
|
}
|
|
|
|
return B_NAME_NOT_FOUND;
|
|
}
|
|
|