Made some necessary enhancements to class Screen; the app_server also

has to care about refresh rates. Also changed Screen::GetMode() (formerly
Resolution()) to return all interesting values, so that hopefully no one
will call it anymore like RootLayer::SetScreens() did.
Greatly improved the horrible RootLayer::SetScreens().
The app_server is now able to deal with failing HWInterface::SetMode() calls;
in this case, it will fall back to the hardware's current mode. This now
also works correctly in combination with the vesa driver, so that you don't
have to compile the app_server with the same resolution you boot in anymore.
SetMode() now always returns if it succeeded or not.
Renamed RootLayer::fScreenXYResolution to fScreenWidth/Height respectively.
Removed the useless DisplayDriver::DisplayMode() method.
Added B_GET_DISPLAY_MODE to the required accelerant hooks.
Some minor cleanup.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@12831 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2005-05-26 09:21:51 +00:00
parent 18b6200e54
commit e5b4782b4e
16 changed files with 254 additions and 196 deletions
@@ -37,8 +37,6 @@ struct vesa_info {
area_id registers_area; area_id registers_area;
struct vesa_shared_info *shared_info; struct vesa_shared_info *shared_info;
area_id shared_area; area_id shared_area;
uint8 *frame_buffer;
area_id frame_buffer_area;
uint8 *reloc_io; uint8 *reloc_io;
area_id reloc_io_area; area_id reloc_io_area;
}; };
+4 -6
View File
@@ -1,5 +1,5 @@
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Copyright (c) 2001-2002, Haiku, Inc. // Copyright (c) 2001-2005, Haiku, Inc.
// //
// Permission is hereby granted, free of charge, to any person obtaining a // Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"), // copy of this software and associated documentation files (the "Software"),
@@ -107,7 +107,7 @@ typedef void (DisplayDriver::* SetRectangleFuncType)(int left, int top, int righ
*/ */
class DisplayDriver { class DisplayDriver {
public: public:
DisplayDriver(); DisplayDriver();
virtual ~DisplayDriver(); virtual ~DisplayDriver();
@@ -313,10 +313,8 @@ class DisplayDriver {
virtual void Unlock() = 0; virtual void Unlock() = 0;
// display mode access // display mode access
virtual void SetMode(const display_mode &mode); virtual status_t SetMode(const display_mode &mode);
virtual void GetMode(display_mode *mode); virtual void GetMode(display_mode &mode);
const display_mode* DisplayMode()
{ return &fDisplayMode; }
virtual bool DumpToFile(const char *path) = 0; virtual bool DumpToFile(const char *path) = 0;
virtual ServerBitmap* DumpToBitmap() = 0; virtual ServerBitmap* DumpToBitmap() = 0;
+4 -1
View File
@@ -150,6 +150,9 @@ vesa_set_display_mode(display_mode *_mode)
if (vesa_propose_display_mode(&mode, &mode, &mode) != B_OK) if (vesa_propose_display_mode(&mode, &mode, &mode) != B_OK)
return B_BAD_VALUE; return B_BAD_VALUE;
// ToDo: unless we have a VBE3 device, we can't change the display mode
return B_UNSUPPORTED;
#if 0
gInfo->shared_info->current_mode = mode; gInfo->shared_info->current_mode = mode;
switch (mode.space) { switch (mode.space) {
@@ -164,8 +167,8 @@ vesa_set_display_mode(display_mode *_mode)
gInfo->shared_info->bytes_per_row = mode.virtual_width; gInfo->shared_info->bytes_per_row = mode.virtual_width;
break; break;
} }
return B_OK; return B_OK;
#endif
} }
@@ -11,8 +11,6 @@
#include <SupportDefs.h> #include <SupportDefs.h>
#include <graphic_driver.h> #include <graphic_driver.h>
#include <image.h> #include <image.h>
#include <boot_item.h>
#include <frame_buffer_console.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@@ -87,16 +85,10 @@ device_open(const char *name, uint32 flags, void **_cookie)
if (info->open_count++ == 0) { if (info->open_count++ == 0) {
// this device has been opened for the first time, so // this device has been opened for the first time, so
// we allocate needed resources and initialize the structure // we allocate needed resources and initialize the structure
if (status == B_OK)
frame_buffer_boot_info *bufferInfo = (frame_buffer_boot_info *)get_boot_item(FRAME_BUFFER_BOOT_INFO); status = vesa_init(*info);
if (bufferInfo != NULL) { if (status == B_OK)
info->frame_buffer = (uint8 *)bufferInfo->frame_buffer; info->id = id;
info->frame_buffer_area = bufferInfo->area;
}
info->id = id;
status = vesa_init(*info);
} }
release_lock(&gLock); release_lock(&gLock);
@@ -4,6 +4,9 @@
*/ */
#include <boot_item.h>
#include <frame_buffer_console.h>
#include "vesa_info.h" #include "vesa_info.h"
#include "driver.h" #include "driver.h"
#include "utility.h" #include "utility.h"
@@ -64,6 +67,11 @@ PhysicalMemoryMapper::Keep()
status_t status_t
vesa_init(vesa_info &info) vesa_init(vesa_info &info)
{ {
frame_buffer_boot_info *bufferInfo
= (frame_buffer_boot_info *)get_boot_item(FRAME_BUFFER_BOOT_INFO);
if (bufferInfo == NULL)
return B_ERROR;
info.shared_area = create_area("vesa shared info", (void **)&info.shared_info, info.shared_area = create_area("vesa shared info", (void **)&info.shared_info,
B_ANY_KERNEL_ADDRESS, B_ANY_KERNEL_ADDRESS,
ROUND_TO_PAGE_SIZE(sizeof(vesa_shared_info)), ROUND_TO_PAGE_SIZE(sizeof(vesa_shared_info)),
@@ -73,11 +81,35 @@ vesa_init(vesa_info &info)
memset((void *)info.shared_info, 0, sizeof(vesa_shared_info)); memset((void *)info.shared_info, 0, sizeof(vesa_shared_info));
info.shared_info->frame_buffer_area = info.frame_buffer_area; info.shared_info->frame_buffer_area = bufferInfo->area;
info.shared_info->frame_buffer = info.frame_buffer; info.shared_info->frame_buffer = (uint8 *)bufferInfo->frame_buffer;
info.shared_info->current_mode.virtual_width = bufferInfo->width;
info.shared_info->current_mode.virtual_height = bufferInfo->height;
switch (bufferInfo->depth) {
case 4:
// ???
break;
case 8:
info.shared_info->current_mode.space = B_CMAP8;
break;
case 15:
info.shared_info->current_mode.space = B_RGB15;
break;
case 16:
info.shared_info->current_mode.space = B_RGB16;
break;
case 24:
info.shared_info->current_mode.space = B_RGB24;
break;
case 32:
info.shared_info->current_mode.space = B_RGB32;
break;
}
info.shared_info->bytes_per_row = bufferInfo->bytes_per_row;
physical_entry mapping; physical_entry mapping;
get_memory_map((void *)info.frame_buffer, B_PAGE_SIZE, &mapping, 1); get_memory_map((void *)info.shared_info->frame_buffer, B_PAGE_SIZE, &mapping, 1);
info.shared_info->physical_frame_buffer = (uint8 *)mapping.address; info.shared_info->physical_frame_buffer = (uint8 *)mapping.address;
dprintf(DEVICE_NAME "vesa_init() completed successfully!\n"); dprintf(DEVICE_NAME "vesa_init() completed successfully!\n");
@@ -90,7 +122,7 @@ vesa_uninit(vesa_info &info)
{ {
dprintf(DEVICE_NAME": vesa_uninit()\n"); dprintf(DEVICE_NAME": vesa_uninit()\n");
delete_area(info.frame_buffer_area); delete_area(info.shared_info->frame_buffer_area);
delete_area(info.shared_area); delete_area(info.shared_area);
} }
+4 -9
View File
@@ -103,15 +103,10 @@ Desktop::AddDriver(DisplayDriver *driver)
{ {
if (driver->Initialize()) { if (driver->Initialize()) {
// TODO: be careful of screen initialization - monitor may not support 640x480 // TODO: be careful of screen initialization - monitor may not support 640x480
Screen *sc = new Screen(driver, BPoint(640, 480), B_RGB32, fScreenList.CountItems()+1); Screen *screen = new Screen(driver, fScreenList.CountItems() + 1);
screen->SetMode(640, 480, B_RGB32, 60.f);
// Screen *sc = new Screen(driver, BPoint(1400, 1050), B_RGB32, fScreenList.CountItems()+1); fScreenList.AddItem(screen);
// Screen *sc = new Screen(driver, BPoint(640, 480), B_CMAP8, fScreenList.CountItems()+1);
// Screen *sc = new Screen(driver, BPoint(640, 480), B_GRAY8, fScreenList.CountItems()+1);
// Screen *sc = new Screen(driver, BPoint(640, 480), B_RGB15, fScreenList.CountItems()+1);
// Screen *sc = new Screen(driver, BPoint(640, 480), B_RGB16, fScreenList.CountItems()+1);
// Screen *sc = new Screen(driver, BPoint(800, 600), B_RGB32, fScreenList.CountItems()+1);
fScreenList.AddItem(sc);
} else { } else {
driver->Shutdown(); driver->Shutdown();
delete driver; delete driver;
@@ -223,7 +218,7 @@ Desktop::CountRootLayers() const
inline DisplayDriver * inline DisplayDriver *
Desktop::GetDisplayDriver() const Desktop::GetDisplayDriver() const
{ {
return ScreenAt(0)->DDriver(); return ScreenAt(0)->GetDisplayDriver();
} }
+49 -55
View File
@@ -63,8 +63,8 @@
static RGBColor kDefaultWorkspaceColor = RGBColor(51, 102, 152); static RGBColor kDefaultWorkspaceColor = RGBColor(51, 102, 152);
RootLayer::RootLayer(const char *name, int32 workspaceCount, RootLayer::RootLayer(const char *name, int32 workspaceCount,
Desktop *desktop, DisplayDriver *driver) Desktop *desktop, DisplayDriver *driver)
: Layer(BRect(0,0,0,0), name, 0, B_FOLLOW_ALL, B_WILL_DRAW, driver) : Layer(BRect(0,0,0,0), name, 0, B_FOLLOW_ALL, B_WILL_DRAW, driver)
{ {
fDesktop = desktop; fDesktop = desktop;
@@ -91,7 +91,6 @@ RootLayer::RootLayer(const char *name, int32 workspaceCount,
fRows = 0; fRows = 0;
fColumns = 0; fColumns = 0;
// easy way to identify this class. // easy way to identify this class.
fClassID = AS_ROOTLAYER_CLASS; fClassID = AS_ROOTLAYER_CLASS;
fHidden = false; fHidden = false;
@@ -103,20 +102,20 @@ RootLayer::RootLayer(const char *name, int32 workspaceCount,
// number to an index in the name, i.e. workspace_settings_1 for screen #1 // number to an index in the name, i.e. workspace_settings_1 for screen #1
// ReadWorkspaceData(WORKSPACE_DATA_LIST); // ReadWorkspaceData(WORKSPACE_DATA_LIST);
// TODO: read these 3 from a configuration file. // TODO: read these 4 from a configuration file.
fScreenXResolution = 0; fScreenWidth = 0;
fScreenYResolution = 0; fScreenHeight = 0;
fColorSpace = B_RGB32; fColorSpace = B_RGB32;
fFrequency = 60.f;
// init the first, default workspace // init the first, default workspace
fActiveWksIndex = 0; fActiveWksIndex = 0;
fWorkspace[fActiveWksIndex] = new Workspace(fActiveWksIndex, 0xFF00FF00, fWorkspace[fActiveWksIndex] = new Workspace(fActiveWksIndex, 0xFF00FF00,
kDefaultWorkspaceColor); kDefaultWorkspaceColor);
fLayerData->SetHighColor(RGBColor(255, 255, 255)); fLayerData->SetHighColor(RGBColor(255, 255, 255));
fLayerData->SetLowColor(fWorkspace[fActiveWksIndex]->BGColor()); fLayerData->SetLowColor(fWorkspace[fActiveWksIndex]->BGColor());
// Spawn our working thread // Spawn our working thread
// fThreadID = spawn_thread(WorkingThread, name, B_REAL_TIME_DISPLAY_PRIORITY, this);
fThreadID = spawn_thread(WorkingThread, name, B_DISPLAY_PRIORITY, this); fThreadID = spawn_thread(WorkingThread, name, B_DISPLAY_PRIORITY, this);
fListenPort = find_port(SERVER_INPUT_PORT); fListenPort = find_port(SERVER_INPUT_PORT);
@@ -129,6 +128,7 @@ RootLayer::RootLayer(const char *name, int32 workspaceCount,
#endif #endif
} }
RootLayer::~RootLayer() RootLayer::~RootLayer()
{ {
int32 exitValue; int32 exitValue;
@@ -148,9 +148,10 @@ RootLayer::~RootLayer()
// RootLayer object just uses Screen objects, it is not allowed to delete them. // RootLayer object just uses Screen objects, it is not allowed to delete them.
} }
void RootLayer::RunThread()
{
void
RootLayer::RunThread()
{
if (fThreadID > 0) if (fThreadID > 0)
resume_thread(fThreadID); resume_thread(fThreadID);
else else
@@ -881,74 +882,63 @@ WinBorder* RootLayer::WinBorderAt(const BPoint& pt) const{
return NULL; return NULL;
} }
void RootLayer::SetScreens(Screen *screen[], int32 rows, int32 columns)
void
RootLayer::SetScreens(Screen *screens[], int32 rows, int32 columns)
{ {
// NOTE: All screens *must* have the same resolution // NOTE: All screens *must* have the same resolution
fScreenPtrList.MakeEmpty(); fScreenPtrList.MakeEmpty();
BRect newFrame(0, 0, 0, 0);
for (int32 i=0; i < rows; i++)
{
if (i==0)
{
for(int32 j=0; j < columns; j++)
{
fScreenPtrList.AddItem(screen[i*rows + j]);
newFrame.right += screen[i*rows + j]->Resolution().x;
}
}
newFrame.bottom += screen[i*rows]->Resolution().y;
}
newFrame.right -= 1; uint16 width, height;
newFrame.bottom -= 1; uint32 colorSpace;
float frequency;
screens[0]->GetMode(width, height, colorSpace, frequency);
fFrame = newFrame; fFrame.Set(0, 0, width * columns - 1, height * rows - 1);
fRows = rows; fRows = rows;
fColumns = columns; fColumns = columns;
fScreenXResolution = (int32)(screen[0]->Resolution().x); fScreenWidth = width;
fScreenYResolution = (int32)(screen[0]->Resolution().y); fScreenHeight = height;
} }
Screen **RootLayer::Screens()
Screen **
RootLayer::Screens()
{ {
return (Screen**)fScreenPtrList.Items(); return (Screen**)fScreenPtrList.Items();
} }
bool RootLayer::SetScreenResolution(int32 width, int32 height, uint32 colorspace)
bool
RootLayer::SetScreenMode(int32 width, int32 height, uint32 colorSpace, float frequency)
{ {
if (fScreenXResolution == width && fScreenYResolution == height && if (fScreenWidth == width && fScreenHeight == height
fColorSpace == colorspace) && fColorSpace == colorSpace && frequency == fFrequency)
return false; return false;
bool accepted = true; bool accepted = true;
for (int i=0; i < fScreenPtrList.CountItems(); i++) for (int i = 0; i < fScreenPtrList.CountItems(); i++) {
{ Screen *screen = static_cast<Screen *>(fScreenPtrList.ItemAt(i));
Screen *screen;
screen = static_cast<Screen*>(fScreenPtrList.ItemAt(i));
if ( !(screen->SupportsResolution(BPoint(width, height), colorspace)) ) if (!(screen->SupportsMode(width, height, colorSpace, frequency)))
accepted = false; accepted = false;
} }
if (accepted) if (!accepted)
{ return false;
for (int i=0; i < fScreenPtrList.CountItems(); i++)
{
Screen *screen;
screen = static_cast<Screen*>(fScreenPtrList.ItemAt(i));
screen->SetResolution(BPoint(width, height), colorspace); for (int i = 0; i < fScreenPtrList.CountItems(); i++) {
} Screen *screen = static_cast<Screen *>(fScreenPtrList.ItemAt(i));
Screen **screens = (Screen**)fScreenPtrList.Items(); screen->SetMode(width, height, colorSpace, frequency);
SetScreens(screens, fRows, fColumns);
return true;
} }
return false; SetScreens(Screens(), fRows, fColumns);
return true;
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
// Workspace related methods // Workspace related methods
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@@ -1797,14 +1787,17 @@ RootLayer::SetDragMessage(BMessage* msg)
fDragMessage = new BMessage(*msg); fDragMessage = new BMessage(*msg);
} }
BMessage* RootLayer::DragMessage(void) const
BMessage *
RootLayer::DragMessage(void) const
{ {
return fDragMessage; return fDragMessage;
} }
// DEBUG methods // DEBUG methods
void RootLayer::PrintToStream() void
RootLayer::PrintToStream()
{ {
printf("\nRootLayer '%s' internals:\n", GetName()); printf("\nRootLayer '%s' internals:\n", GetName());
printf("Screen list:\n"); printf("Screen list:\n");
@@ -1812,7 +1805,7 @@ void RootLayer::PrintToStream()
printf("\t%ld\n", ((Screen*)fScreenPtrList.ItemAt(i))->ScreenNumber()); printf("\t%ld\n", ((Screen*)fScreenPtrList.ItemAt(i))->ScreenNumber());
printf("Screen rows: %ld\nScreen columns: %ld\n", fRows, fColumns); printf("Screen rows: %ld\nScreen columns: %ld\n", fRows, fColumns);
printf("Resolution for all Screens: %ldx%ldx%ld\n", fScreenXResolution, fScreenYResolution, fColorSpace); printf("Resolution for all Screens: %ldx%ldx%ld\n", fScreenWidth, fScreenHeight, fColorSpace);
printf("Workspace list:\n"); printf("Workspace list:\n");
for(int32 i=0; i<fWsCount; i++) for(int32 i=0; i<fWsCount; i++)
{ {
@@ -1824,7 +1817,8 @@ void RootLayer::PrintToStream()
// PRIVATE methods // PRIVATE methods
void RootLayer::show_winBorder(WinBorder *winBorder) void
RootLayer::show_winBorder(WinBorder *winBorder)
{ {
bool invalidate = false; bool invalidate = false;
bool invalid; bool invalid;
+7 -5
View File
@@ -54,8 +54,7 @@ class BPortLink;
Layer functions to act accordingly. There is only one for each workspace class. Layer functions to act accordingly. There is only one for each workspace class.
*/ */
class RootLayer : public Layer class RootLayer : public Layer {
{
public: public:
RootLayer(const char *name, int32 workspaceCount, RootLayer(const char *name, int32 workspaceCount,
Desktop *desktop, DisplayDriver *driver); Desktop *desktop, DisplayDriver *driver);
@@ -97,7 +96,7 @@ public:
void SetScreens(Screen *screen[], int32 rows, int32 columns); void SetScreens(Screen *screen[], int32 rows, int32 columns);
Screen** Screens(void); Screen** Screens(void);
bool SetScreenResolution(int32 width, int32 height, uint32 colorspace); bool SetScreenMode(int32 width, int32 height, uint32 colorspace, float frequency);
int32 ScreenRows(void) const { return fRows; } int32 ScreenRows(void) const { return fRows; }
int32 ScreenColumns(void) const { return fColumns; } int32 ScreenColumns(void) const { return fColumns; }
@@ -179,9 +178,12 @@ friend class Desktop;
BList fScreenPtrList; BList fScreenPtrList;
int32 fRows; int32 fRows;
int32 fColumns; int32 fColumns;
int32 fScreenXResolution;
int32 fScreenYResolution; int32 fScreenWidth;
int32 fScreenHeight;
uint32 fColorSpace; uint32 fColorSpace;
float fFrequency;
int32 fButtons; int32 fButtons;
BPoint fLastMousePossition; BPoint fLastMousePossition;
bool fMovingWindow; bool fMovingWindow;
+1 -1
View File
@@ -1896,7 +1896,7 @@ ServerApp::DispatchMessage(int32 code, LinkMsgReader &msg)
// We have the screen_id and the workspace number, with these // We have the screen_id and the workspace number, with these
// we need to find the corresponding "driver", and call getmode on it // we need to find the corresponding "driver", and call getmode on it
display_mode mode; display_mode mode;
desktop->GetDisplayDriver()->GetMode(&mode); desktop->GetDisplayDriver()->GetMode(mode);
// actually this isn't still enough as different workspaces can // actually this isn't still enough as different workspaces can
// have different display_modes // have different display_modes
+50 -34
View File
@@ -1,5 +1,5 @@
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Copyright (c) 2001-2002, Haiku, Inc. // Copyright (c) 2001-2005, Haiku, Inc.
// //
// Permission is hereby granted, free of charge, to any person obtaining a // Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"), // copy of this software and associated documentation files (the "Software"),
@@ -21,24 +21,31 @@
// //
// File Name: ServerScreen.cpp // File Name: ServerScreen.cpp
// Author: Adi Oanca <[email protected]> // Author: Adi Oanca <[email protected]>
// Axel Dörfler, [email protected]
// Description: Handles individual screens // Description: Handles individual screens
// //
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
#include <Accelerant.h> #include <Accelerant.h>
#include <Point.h> #include <Point.h>
#include <GraphicsDefs.h> #include <GraphicsDefs.h>
#include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include "ServerScreen.h" #include "ServerScreen.h"
#include "DisplayDriver.h" #include "DisplayDriver.h"
Screen::Screen(DisplayDriver *dDriver, BPoint res, uint32 colorspace, const int32 &ID)
Screen::Screen(DisplayDriver *driver, int32 id)
:
fID(id),
fDriver(driver)
{ {
fID = ID;
fDDriver = dDriver;
SetResolution(res, colorspace);
} }
Screen::~Screen(void) Screen::~Screen(void)
{ {
//printf("~Screen( %ld )\n", fID); //printf("~Screen( %ld )\n", fID);
@@ -46,64 +53,73 @@ Screen::~Screen(void)
// delete fDDriver; // delete fDDriver;
} }
bool Screen::SupportsResolution(BPoint res, uint32 colorspace)
bool
Screen::SupportsMode(uint16 width, uint16 height, uint32 colorspace, float frequency)
{ {
// TODO: remove/improve // TODO: remove/improve
return true; return true;
display_mode *dm = NULL; display_mode *dm = NULL;
uint32 count; uint32 count;
status_t err = fDDriver->GetModeList(&dm, &count); status_t err = fDriver->GetModeList(&dm, &count);
if (err < B_OK) { if (err < B_OK) {
// We've run into quite a problem here! This is a function which is a requirement // We've run into quite a problem here! This is a function which is a requirement
// for a graphics module. The best thing that we can hope for is 640x480x8 without // for a graphics module. The best thing that we can hope for is 640x480x8 without
// knowing anything else. While even this seems like insanity to assume that we // knowing anything else. While even this seems like insanity to assume that we
// can support this, the only lower mode supported is 640x400, but we shouldn't even // can support this, the only lower mode supported is 640x400, but we shouldn't even
// bother with such a pathetic possibility. // bother with such a pathetic possibility.
if ((uint16)res.x == 640 && (uint16)res.y == 480 && colorspace == B_CMAP8) if (width == 640 && height == 480 && colorspace == B_CMAP8)
return true; return true;
else
return false; return false;
} }
for (uint32 i=0; i < count; i++) for (uint32 i = 0; i < count; i++) {
{ if (dm[i].virtual_width == width
if (dm[i].virtual_width == (uint16)res.x && && dm[i].virtual_height == height
dm[i].virtual_height == (uint16)res.y && && dm[i].space == colorspace)
dm[i].space == colorspace)
return true; return true;
} }
delete [] dm; free(dm);
return false; return false;
} }
bool Screen::SetResolution(BPoint res, uint32 colorspace)
bool
Screen::SetMode(uint16 width, uint16 height, uint32 colorspace, float frequency)
{ {
if (!SupportsResolution(res, colorspace)) if (!SupportsMode(width, height, colorspace, frequency))
return false; return false;
display_mode mode; display_mode mode;
mode.virtual_width = width;
mode.virtual_height = height;
mode.space = colorspace;
// ToDo: frequency!
// (we need to search the mode list for this)
mode.virtual_width = (uint16)res.x; return fDriver->SetMode(mode) >= B_OK;
mode.virtual_height = (uint16)res.y;
mode.space = colorspace;
fDDriver->SetMode(mode);
return true;
} }
BPoint Screen::Resolution() const
void
Screen::GetMode(uint16 &width, uint16 &height, uint32 &colorspace, float &frequency) const
{ {
display_mode mode; display_mode mode;
fDriver->GetMode(mode);
fDDriver->GetMode(&mode); width = mode.virtual_width;
height = mode.virtual_height;
return BPoint(mode.virtual_width, mode.virtual_height); colorspace = mode.space;
frequency = mode.timing.pixel_clock * 1000.f
/ (mode.timing.h_total * mode.timing.v_total);
} }
int32 Screen::ScreenNumber(void) const
int32
Screen::ScreenNumber(void) const
{ {
return fID; return fID;
} }
+14 -12
View File
@@ -1,5 +1,5 @@
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Copyright (c) 2001-2002, Haiku, Inc. // Copyright (c) 2001-2005, Haiku, Inc.
// //
// Permission is hereby granted, free of charge, to any person obtaining a // Permission is hereby granted, free of charge, to any person obtaining a
// copy of this software and associated documentation files (the "Software"), // copy of this software and associated documentation files (the "Software"),
@@ -21,33 +21,35 @@
// //
// File Name: ServerScreen.h // File Name: ServerScreen.h
// Author: Adi Oanca <[email protected]> // Author: Adi Oanca <[email protected]>
// Axel Dörfler, [email protected]
// Description: Handles individual screens // Description: Handles individual screens
// //
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
#ifndef _SCREEN_H_ #ifndef _SCREEN_H_
#define _SCREEN_H_ #define _SCREEN_H_
#include <Point.h> #include <Point.h>
class DisplayDriver; class DisplayDriver;
class Screen class Screen {
{
public: public:
Screen(DisplayDriver *dDriver, BPoint res, uint32 colorspace, const int32 &ID); Screen(DisplayDriver *driver, int32 id);
Screen(){ ; } Screen() {}
~Screen(void); ~Screen(void);
void SetID(int32 ID){ fID = ID; } void SetID(int32 ID) { fID = ID; }
bool SupportsResolution(BPoint res, uint32 colorspace); bool SupportsMode(uint16 width, uint16 height, uint32 colorspace, float frequency);
bool SetResolution(BPoint res, uint32 colorspace); bool SetMode(uint16 width, uint16 height, uint32 colorspace, float frequency);
BPoint Resolution() const; void GetMode(uint16 &width, uint16 &height, uint32 &colorspace, float &frequency) const;
int32 ScreenNumber(void) const; int32 ScreenNumber(void) const;
DisplayDriver* DDriver() const { return fDDriver; } DisplayDriver *GetDisplayDriver() const { return fDriver; }
private: private:
int32 fID; int32 fID;
DisplayDriver *fDDriver; DisplayDriver *fDriver;
}; };
#endif #endif /* _SCREEN_H_ */
@@ -59,6 +59,7 @@ AccelerantHWInterface::AccelerantHWInterface()
fAccGetModeList(NULL), fAccGetModeList(NULL),
fAccGetFrameBufferConfig(NULL), fAccGetFrameBufferConfig(NULL),
fAccSetDisplayMode(NULL), fAccSetDisplayMode(NULL),
fAccGetDisplayMode(NULL),
fAccGetPixelClockLimits(NULL), fAccGetPixelClockLimits(NULL),
// optional accelerant hooks // optional accelerant hooks
@@ -260,11 +261,12 @@ AccelerantHWInterface::SetupDefaultHooks()
fAccGetModeList = (get_mode_list)fAccelerantHook(B_GET_MODE_LIST, NULL); fAccGetModeList = (get_mode_list)fAccelerantHook(B_GET_MODE_LIST, NULL);
fAccGetFrameBufferConfig = (get_frame_buffer_config)fAccelerantHook(B_GET_FRAME_BUFFER_CONFIG, NULL); fAccGetFrameBufferConfig = (get_frame_buffer_config)fAccelerantHook(B_GET_FRAME_BUFFER_CONFIG, NULL);
fAccSetDisplayMode = (set_display_mode)fAccelerantHook(B_SET_DISPLAY_MODE, NULL); fAccSetDisplayMode = (set_display_mode)fAccelerantHook(B_SET_DISPLAY_MODE, NULL);
fAccGetDisplayMode = (get_display_mode)fAccelerantHook(B_GET_DISPLAY_MODE, NULL);
fAccGetPixelClockLimits = (get_pixel_clock_limits)fAccelerantHook(B_GET_PIXEL_CLOCK_LIMITS, NULL); fAccGetPixelClockLimits = (get_pixel_clock_limits)fAccelerantHook(B_GET_PIXEL_CLOCK_LIMITS, NULL);
if (!fAccAcquireEngine || !fAccReleaseEngine || !fAccGetFrameBufferConfig if (!fAccAcquireEngine || !fAccReleaseEngine || !fAccGetFrameBufferConfig
|| !fAccGetModeCount || !fAccGetModeList || !fAccSetDisplayMode || !fAccGetModeCount || !fAccGetModeList || !fAccSetDisplayMode
|| !fAccGetPixelClockLimits) { || !fAccGetDisplayMode || !fAccGetPixelClockLimits) {
return B_ERROR; return B_ERROR;
} }
@@ -345,7 +347,10 @@ AccelerantHWInterface::SetMode(const display_mode &mode)
if (fAccSetDisplayMode(&fDisplayMode) != B_OK) { if (fAccSetDisplayMode(&fDisplayMode) != B_OK) {
ATRACE(("setting display mode failed\n")); ATRACE(("setting display mode failed\n"));
return B_ERROR; fAccGetDisplayMode(&fDisplayMode);
// We just keep the current mode and continue.
// Note, on startup, this may be different from
// what we think is the current display mode
} }
// update frontbuffer // update frontbuffer
@@ -389,6 +394,7 @@ AccelerantHWInterface::SetMode(const display_mode &mode)
return B_OK; return B_OK;
} }
void void
AccelerantHWInterface::GetMode(display_mode *mode) AccelerantHWInterface::GetMode(display_mode *mode)
{ {
@@ -396,6 +402,7 @@ AccelerantHWInterface::GetMode(display_mode *mode)
*mode = fDisplayMode; *mode = fDisplayMode;
} }
status_t status_t
AccelerantHWInterface::UpdateModeList() AccelerantHWInterface::UpdateModeList()
{ {
@@ -403,7 +410,7 @@ AccelerantHWInterface::UpdateModeList()
if (fModeCount <= 0) if (fModeCount <= 0)
return B_ERROR; return B_ERROR;
fModeList = new display_mode[fModeCount];; fModeList = new display_mode[fModeCount];
if (!fModeList) if (!fModeList)
return B_NO_MEMORY; return B_NO_MEMORY;
@@ -415,6 +422,7 @@ AccelerantHWInterface::UpdateModeList()
return B_OK; return B_OK;
} }
status_t status_t
AccelerantHWInterface::UpdateFrameBufferConfig() AccelerantHWInterface::UpdateFrameBufferConfig()
{ {
@@ -96,6 +96,7 @@ private:
get_mode_list fAccGetModeList; get_mode_list fAccGetModeList;
get_frame_buffer_config fAccGetFrameBufferConfig; get_frame_buffer_config fAccGetFrameBufferConfig;
set_display_mode fAccSetDisplayMode; set_display_mode fAccSetDisplayMode;
get_display_mode fAccGetDisplayMode;
get_pixel_clock_limits fAccGetPixelClockLimits; get_pixel_clock_limits fAccGetPixelClockLimits;
// optional accelerant hooks // optional accelerant hooks
+6 -6
View File
@@ -95,24 +95,24 @@ DisplayDriver::Shutdown()
Subclasses must include calls to _SetDepth, _SetHeight, _SetWidth, and _SetMode Subclasses must include calls to _SetDepth, _SetHeight, _SetWidth, and _SetMode
to update the state variables kept internally by the DisplayDriver class. to update the state variables kept internally by the DisplayDriver class.
*/ */
void status_t
DisplayDriver::SetMode(const display_mode &mode) DisplayDriver::SetMode(const display_mode &mode)
{ {
if (Lock()) { if (Lock()) {
fDisplayMode = mode; fDisplayMode = mode;
Unlock(); Unlock();
return B_OK;
} }
return B_ERROR;
} }
// GetMode // GetMode
void void
DisplayDriver::GetMode(display_mode *mode) DisplayDriver::GetMode(display_mode &mode)
{ {
if (!mode)
return;
if (Lock()) { if (Lock()) {
*mode = fDisplayMode; mode = fDisplayMode;
Unlock(); Unlock();
} }
} }
@@ -78,6 +78,7 @@ DisplayDriverPainter::Initialize()
fAvailableHWAccleration = fGraphicsCard->AvailableHWAcceleration(); fAvailableHWAccleration = fGraphicsCard->AvailableHWAcceleration();
return DisplayDriver::Initialize(); return DisplayDriver::Initialize();
} }
return false; return false;
} }
@@ -1181,19 +1182,24 @@ DisplayDriverPainter::Unlock()
} }
// SetMode // SetMode
void status_t
DisplayDriverPainter::SetMode(const display_mode &mode) DisplayDriverPainter::SetMode(const display_mode &mode)
{ {
status_t status = B_ERROR;
if (Lock()) { if (Lock()) {
if (fGraphicsCard->SetMode(mode) >= B_OK) { status = fGraphicsCard->SetMode(mode);
if (status >= B_OK) {
fPainter->AttachToBuffer(fGraphicsCard->DrawingBuffer()); fPainter->AttachToBuffer(fGraphicsCard->DrawingBuffer());
DisplayDriver::SetMode(mode); status = DisplayDriver::SetMode(mode);
} else { } else {
fprintf(stderr, "DisplayDriverPainter::SetMode() - unsupported " fprintf(stderr, "DisplayDriverPainter::SetMode() - unsupported "
"mode!\n"); "mode!\n");
} }
Unlock(); Unlock();
} }
return status;
} }
// DumpToFile // DumpToFile
@@ -1282,6 +1288,16 @@ DisplayDriverPainter::GetModeList(display_mode **mode_list, uint32 *count)
return ret; return ret;
} }
// GetMode
void
DisplayDriverPainter::GetMode(display_mode &mode)
{
if (Lock()) {
fGraphicsCard->GetMode(&mode);
Unlock();
}
}
// GetPixelClockLimits // GetPixelClockLimits
status_t DisplayDriverPainter::GetPixelClockLimits(display_mode *mode, status_t DisplayDriverPainter::GetPixelClockLimits(display_mode *mode,
uint32 *low, uint32 *low,
@@ -37,7 +37,7 @@ class HWInterface;
class Painter; class Painter;
class DisplayDriverPainter : public DisplayDriver { class DisplayDriverPainter : public DisplayDriver {
public: public:
DisplayDriverPainter(); DisplayDriverPainter();
virtual ~DisplayDriverPainter(); virtual ~DisplayDriverPainter();
@@ -241,7 +241,8 @@ class DisplayDriverPainter : public DisplayDriver {
virtual void Unlock(); virtual void Unlock();
// display mode access // display mode access
virtual void SetMode(const display_mode &mode); virtual status_t SetMode(const display_mode &mode);
virtual void GetMode(display_mode &mode);
virtual bool DumpToFile(const char *path); virtual bool DumpToFile(const char *path);
virtual ServerBitmap* DumpToBitmap(); virtual ServerBitmap* DumpToBitmap();