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

View File

@ -37,8 +37,6 @@ struct vesa_info {
area_id registers_area;
struct vesa_shared_info *shared_info;
area_id shared_area;
uint8 *frame_buffer;
area_id frame_buffer_area;
uint8 *reloc_io;
area_id reloc_io_area;
};

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
// 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 {
public:
public:
DisplayDriver();
virtual ~DisplayDriver();
@ -313,11 +313,9 @@ class DisplayDriver {
virtual void Unlock() = 0;
// display mode access
virtual void SetMode(const display_mode &mode);
virtual void GetMode(display_mode *mode);
const display_mode* DisplayMode()
{ return &fDisplayMode; }
virtual status_t SetMode(const display_mode &mode);
virtual void GetMode(display_mode &mode);
virtual bool DumpToFile(const char *path) = 0;
virtual ServerBitmap* DumpToBitmap() = 0;

View File

@ -150,6 +150,9 @@ vesa_set_display_mode(display_mode *_mode)
if (vesa_propose_display_mode(&mode, &mode, &mode) != B_OK)
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;
switch (mode.space) {
@ -164,8 +167,8 @@ vesa_set_display_mode(display_mode *_mode)
gInfo->shared_info->bytes_per_row = mode.virtual_width;
break;
}
return B_OK;
#endif
}

View File

@ -11,8 +11,6 @@
#include <SupportDefs.h>
#include <graphic_driver.h>
#include <image.h>
#include <boot_item.h>
#include <frame_buffer_console.h>
#include <stdlib.h>
#include <string.h>
@ -87,16 +85,10 @@ device_open(const char *name, uint32 flags, void **_cookie)
if (info->open_count++ == 0) {
// this device has been opened for the first time, so
// we allocate needed resources and initialize the structure
frame_buffer_boot_info *bufferInfo = (frame_buffer_boot_info *)get_boot_item(FRAME_BUFFER_BOOT_INFO);
if (bufferInfo != NULL) {
info->frame_buffer = (uint8 *)bufferInfo->frame_buffer;
info->frame_buffer_area = bufferInfo->area;
}
info->id = id;
status = vesa_init(*info);
if (status == B_OK)
status = vesa_init(*info);
if (status == B_OK)
info->id = id;
}
release_lock(&gLock);

View File

@ -4,6 +4,9 @@
*/
#include <boot_item.h>
#include <frame_buffer_console.h>
#include "vesa_info.h"
#include "driver.h"
#include "utility.h"
@ -64,6 +67,11 @@ PhysicalMemoryMapper::Keep()
status_t
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,
B_ANY_KERNEL_ADDRESS,
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));
info.shared_info->frame_buffer_area = info.frame_buffer_area;
info.shared_info->frame_buffer = info.frame_buffer;
info.shared_info->frame_buffer_area = bufferInfo->area;
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;
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;
dprintf(DEVICE_NAME "vesa_init() completed successfully!\n");
@ -90,7 +122,7 @@ vesa_uninit(vesa_info &info)
{
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);
}

View File

@ -103,15 +103,10 @@ Desktop::AddDriver(DisplayDriver *driver)
{
if (driver->Initialize()) {
// 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);
// 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);
fScreenList.AddItem(screen);
} else {
driver->Shutdown();
delete driver;
@ -223,7 +218,7 @@ Desktop::CountRootLayers() const
inline DisplayDriver *
Desktop::GetDisplayDriver() const
{
return ScreenAt(0)->DDriver();
return ScreenAt(0)->GetDisplayDriver();
}

View File

@ -63,8 +63,8 @@
static RGBColor kDefaultWorkspaceColor = RGBColor(51, 102, 152);
RootLayer::RootLayer(const char *name, int32 workspaceCount,
Desktop *desktop, DisplayDriver *driver)
: Layer(BRect(0,0,0,0), name, 0, B_FOLLOW_ALL, B_WILL_DRAW, driver)
Desktop *desktop, DisplayDriver *driver)
: Layer(BRect(0,0,0,0), name, 0, B_FOLLOW_ALL, B_WILL_DRAW, driver)
{
fDesktop = desktop;
@ -91,7 +91,6 @@ RootLayer::RootLayer(const char *name, int32 workspaceCount,
fRows = 0;
fColumns = 0;
// easy way to identify this class.
fClassID = AS_ROOTLAYER_CLASS;
fHidden = false;
@ -103,22 +102,22 @@ RootLayer::RootLayer(const char *name, int32 workspaceCount,
// number to an index in the name, i.e. workspace_settings_1 for screen #1
// ReadWorkspaceData(WORKSPACE_DATA_LIST);
// TODO: read these 3 from a configuration file.
fScreenXResolution = 0;
fScreenYResolution = 0;
// TODO: read these 4 from a configuration file.
fScreenWidth = 0;
fScreenHeight = 0;
fColorSpace = B_RGB32;
fFrequency = 60.f;
// init the first, default workspace
fActiveWksIndex = 0;
fActiveWksIndex = 0;
fWorkspace[fActiveWksIndex] = new Workspace(fActiveWksIndex, 0xFF00FF00,
kDefaultWorkspaceColor);
fLayerData->SetHighColor(RGBColor(255, 255, 255));
fLayerData->SetLowColor(fWorkspace[fActiveWksIndex]->BGColor());
// Spawn our working thread
// fThreadID = spawn_thread(WorkingThread, name, B_REAL_TIME_DISPLAY_PRIORITY, this);
fThreadID = spawn_thread(WorkingThread, name, B_DISPLAY_PRIORITY, this);
fListenPort = find_port(SERVER_INPUT_PORT);
if (fListenPort == B_NAME_NOT_FOUND) {
fListenPort = -1;
@ -129,6 +128,7 @@ RootLayer::RootLayer(const char *name, int32 workspaceCount,
#endif
}
RootLayer::~RootLayer()
{
int32 exitValue;
@ -148,9 +148,10 @@ RootLayer::~RootLayer()
// RootLayer object just uses Screen objects, it is not allowed to delete them.
}
void RootLayer::RunThread()
void
RootLayer::RunThread()
{
if (fThreadID > 0)
resume_thread(fThreadID);
else
@ -881,74 +882,63 @@ WinBorder* RootLayer::WinBorderAt(const BPoint& pt) const{
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
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;
newFrame.bottom -= 1;
fFrame = newFrame;
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;
fScreenXResolution = (int32)(screen[0]->Resolution().x);
fScreenYResolution = (int32)(screen[0]->Resolution().y);
fScreenWidth = width;
fScreenHeight = height;
}
Screen **RootLayer::Screens()
Screen **
RootLayer::Screens()
{
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 &&
fColorSpace == colorspace)
if (fScreenWidth == width && fScreenHeight == height
&& fColorSpace == colorSpace && frequency == fFrequency)
return false;
bool accepted = true;
for (int i=0; i < fScreenPtrList.CountItems(); i++)
{
Screen *screen;
screen = static_cast<Screen*>(fScreenPtrList.ItemAt(i));
if ( !(screen->SupportsResolution(BPoint(width, height), colorspace)) )
for (int i = 0; i < fScreenPtrList.CountItems(); i++) {
Screen *screen = static_cast<Screen *>(fScreenPtrList.ItemAt(i));
if (!(screen->SupportsMode(width, height, colorSpace, frequency)))
accepted = false;
}
if (accepted)
{
for (int i=0; i < fScreenPtrList.CountItems(); i++)
{
Screen *screen;
screen = static_cast<Screen*>(fScreenPtrList.ItemAt(i));
screen->SetResolution(BPoint(width, height), colorspace);
}
Screen **screens = (Screen**)fScreenPtrList.Items();
SetScreens(screens, fRows, fColumns);
return true;
if (!accepted)
return false;
for (int i = 0; i < fScreenPtrList.CountItems(); i++) {
Screen *screen = static_cast<Screen *>(fScreenPtrList.ItemAt(i));
screen->SetMode(width, height, colorSpace, frequency);
}
return false;
SetScreens(Screens(), fRows, fColumns);
return true;
}
//---------------------------------------------------------------------------
// Workspace related methods
//---------------------------------------------------------------------------
@ -1797,14 +1787,17 @@ RootLayer::SetDragMessage(BMessage* msg)
fDragMessage = new BMessage(*msg);
}
BMessage* RootLayer::DragMessage(void) const
BMessage *
RootLayer::DragMessage(void) const
{
return fDragMessage;
}
// DEBUG methods
void RootLayer::PrintToStream()
void
RootLayer::PrintToStream()
{
printf("\nRootLayer '%s' internals:\n", GetName());
printf("Screen list:\n");
@ -1812,7 +1805,7 @@ void RootLayer::PrintToStream()
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", fScreenXResolution, fScreenYResolution, fColorSpace);
printf("Resolution for all Screens: %ldx%ldx%ld\n", fScreenWidth, fScreenHeight, fColorSpace);
printf("Workspace list:\n");
for(int32 i=0; i<fWsCount; i++)
{
@ -1824,7 +1817,8 @@ void RootLayer::PrintToStream()
// PRIVATE methods
void RootLayer::show_winBorder(WinBorder *winBorder)
void
RootLayer::show_winBorder(WinBorder *winBorder)
{
bool invalidate = false;
bool invalid;

View File

@ -54,8 +54,7 @@ class BPortLink;
Layer functions to act accordingly. There is only one for each workspace class.
*/
class RootLayer : public Layer
{
class RootLayer : public Layer {
public:
RootLayer(const char *name, int32 workspaceCount,
Desktop *desktop, DisplayDriver *driver);
@ -97,7 +96,7 @@ public:
void SetScreens(Screen *screen[], int32 rows, int32 columns);
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 ScreenColumns(void) const { return fColumns; }
@ -179,9 +178,12 @@ friend class Desktop;
BList fScreenPtrList;
int32 fRows;
int32 fColumns;
int32 fScreenXResolution;
int32 fScreenYResolution;
int32 fScreenWidth;
int32 fScreenHeight;
uint32 fColorSpace;
float fFrequency;
int32 fButtons;
BPoint fLastMousePossition;
bool fMovingWindow;

View File

@ -1896,7 +1896,7 @@ ServerApp::DispatchMessage(int32 code, LinkMsgReader &msg)
// We have the screen_id and the workspace number, with these
// we need to find the corresponding "driver", and call getmode on it
display_mode mode;
desktop->GetDisplayDriver()->GetMode(&mode);
desktop->GetDisplayDriver()->GetMode(mode);
// actually this isn't still enough as different workspaces can
// have different display_modes

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
// copy of this software and associated documentation files (the "Software"),
@ -21,24 +21,31 @@
//
// File Name: ServerScreen.cpp
// Author: Adi Oanca <adioanca@myrealbox.com>
// Axel Dörfler, axeld@pinc-software.de
// Description: Handles individual screens
//
//
//------------------------------------------------------------------------------
#include <Accelerant.h>
#include <Point.h>
#include <GraphicsDefs.h>
#include <stdlib.h>
#include <stdio.h>
#include "ServerScreen.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)
{
//printf("~Screen( %ld )\n", fID);
@ -46,64 +53,73 @@ Screen::~Screen(void)
// delete fDDriver;
}
bool Screen::SupportsResolution(BPoint res, uint32 colorspace)
bool
Screen::SupportsMode(uint16 width, uint16 height, uint32 colorspace, float frequency)
{
// TODO: remove/improve
return true;
display_mode *dm = NULL;
uint32 count;
display_mode *dm = NULL;
uint32 count;
status_t err = fDDriver->GetModeList(&dm, &count);
status_t err = fDriver->GetModeList(&dm, &count);
if (err < B_OK) {
// 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
// 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
// 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;
else
return false;
return false;
}
for (uint32 i=0; i < count; i++)
{
if (dm[i].virtual_width == (uint16)res.x &&
dm[i].virtual_height == (uint16)res.y &&
dm[i].space == colorspace)
for (uint32 i = 0; i < count; i++) {
if (dm[i].virtual_width == width
&& dm[i].virtual_height == height
&& dm[i].space == colorspace)
return true;
}
delete [] dm;
free(dm);
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;
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;
mode.virtual_height = (uint16)res.y;
mode.space = colorspace;
fDDriver->SetMode(mode);
return true;
return fDriver->SetMode(mode) >= B_OK;
}
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);
return BPoint(mode.virtual_width, mode.virtual_height);
width = mode.virtual_width;
height = 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;
}

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
// copy of this software and associated documentation files (the "Software"),
@ -21,33 +21,35 @@
//
// File Name: ServerScreen.h
// Author: Adi Oanca <adioanca@myrealbox.com>
// Axel Dörfler, axeld@pinc-software.de
// Description: Handles individual screens
//
//
//------------------------------------------------------------------------------
#ifndef _SCREEN_H_
#define _SCREEN_H_
#include <Point.h>
class DisplayDriver;
class Screen
{
class Screen {
public:
Screen(DisplayDriver *dDriver, BPoint res, uint32 colorspace, const int32 &ID);
Screen(){ ; }
Screen(DisplayDriver *driver, int32 id);
Screen() {}
~Screen(void);
void SetID(int32 ID){ fID = ID; }
bool SupportsResolution(BPoint res, uint32 colorspace);
bool SetResolution(BPoint res, uint32 colorspace);
BPoint Resolution() const;
void SetID(int32 ID) { fID = ID; }
bool SupportsMode(uint16 width, uint16 height, uint32 colorspace, float frequency);
bool SetMode(uint16 width, uint16 height, uint32 colorspace, float frequency);
void GetMode(uint16 &width, uint16 &height, uint32 &colorspace, float &frequency) const;
int32 ScreenNumber(void) const;
DisplayDriver* DDriver() const { return fDDriver; }
DisplayDriver *GetDisplayDriver() const { return fDriver; }
private:
int32 fID;
DisplayDriver *fDDriver;
DisplayDriver *fDriver;
};
#endif
#endif /* _SCREEN_H_ */

View File

@ -50,7 +50,7 @@ AccelerantHWInterface::AccelerantHWInterface()
fAccelerantHook(NULL),
fEngineToken(NULL),
fSyncToken(),
// required hooks
fAccAcquireEngine(NULL),
fAccReleaseEngine(NULL),
@ -59,8 +59,9 @@ AccelerantHWInterface::AccelerantHWInterface()
fAccGetModeList(NULL),
fAccGetFrameBufferConfig(NULL),
fAccSetDisplayMode(NULL),
fAccGetDisplayMode(NULL),
fAccGetPixelClockLimits(NULL),
// optional accelerant hooks
fAccGetTimingConstraints(NULL),
fAccProposeDisplayMode(NULL),
@ -70,15 +71,15 @@ AccelerantHWInterface::AccelerantHWInterface()
fAccSetCursorShape(NULL),
fAccMoveCursor(NULL),
fAccShowCursor(NULL),
// dpms hooks
fAccDPMSCapabilities(NULL),
fAccDPMSMode(NULL),
fAccSetDPMSMode(NULL),
fModeCount(0),
fModeList(NULL),
fBackBuffer(NULL),
fFrontBuffer(new AccelerantBuffer())
{
@ -260,31 +261,32 @@ AccelerantHWInterface::SetupDefaultHooks()
fAccGetModeList = (get_mode_list)fAccelerantHook(B_GET_MODE_LIST, NULL);
fAccGetFrameBufferConfig = (get_frame_buffer_config)fAccelerantHook(B_GET_FRAME_BUFFER_CONFIG, 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);
if (!fAccAcquireEngine || !fAccReleaseEngine || !fAccGetFrameBufferConfig
|| !fAccGetModeCount || !fAccGetModeList || !fAccSetDisplayMode
|| !fAccGetPixelClockLimits) {
|| !fAccGetDisplayMode || !fAccGetPixelClockLimits) {
return B_ERROR;
}
// optional
fAccGetTimingConstraints = (get_timing_constraints)fAccelerantHook(B_GET_TIMING_CONSTRAINTS, NULL);
fAccProposeDisplayMode = (propose_display_mode)fAccelerantHook(B_PROPOSE_DISPLAY_MODE, NULL);
fAccFillRect = (fill_rectangle)fAccelerantHook(B_FILL_RECTANGLE, NULL);
fAccInvertRect = (invert_rectangle)fAccelerantHook(B_INVERT_RECTANGLE, NULL);
fAccScreenBlit = (screen_to_screen_blit)fAccelerantHook(B_SCREEN_TO_SCREEN_BLIT, NULL);
fAccSetCursorShape = (set_cursor_shape)fAccelerantHook(B_SET_CURSOR_SHAPE, NULL);
fAccMoveCursor = (move_cursor)fAccelerantHook(B_MOVE_CURSOR, NULL);
fAccShowCursor = (show_cursor)fAccelerantHook(B_SHOW_CURSOR, NULL);
// dpms
fAccDPMSCapabilities = (dpms_capabilities)fAccelerantHook(B_DPMS_CAPABILITIES, NULL);
fAccDPMSMode = (dpms_mode)fAccelerantHook(B_DPMS_MODE, NULL);
fAccSetDPMSMode = (set_dpms_mode)fAccelerantHook(B_SET_DPMS_MODE, NULL);
return B_OK;
}
@ -322,37 +324,40 @@ AccelerantHWInterface::SetMode(const display_mode &mode)
&& fDisplayMode.space == mode.space) {
return B_OK;
}
// TODO: check if the mode is valid even (ie complies to the modes we said we would support)
// or else ret = B_BAD_VALUE
if (fModeCount <= 0 || !fModeList) {
if (UpdateModeList() != B_OK || fModeCount <= 0) {
ATRACE(("unable to update mode list\n"));
return B_ERROR;
}
}
for (int32 i = 0; i < fModeCount; i++) {
if (fModeList[i].virtual_width == mode.virtual_width
&& fModeList[i].virtual_height == mode.virtual_height
&& fModeList[i].space == mode.space) {
fDisplayMode = fModeList[i];
break;
}
}
if (fAccSetDisplayMode(&fDisplayMode) != B_OK) {
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
fFrontBuffer->SetDisplayMode(fDisplayMode);
if (UpdateFrameBufferConfig() != B_OK)
return B_ERROR;
// update backbuffer if neccessary
if (!fBackBuffer || fBackBuffer->Width() != fDisplayMode.virtual_width
|| fBackBuffer->Height() != fDisplayMode.virtual_height) {
@ -370,11 +375,11 @@ AccelerantHWInterface::SetMode(const display_mode &mode)
if ((color_space)fDisplayMode.space != B_RGB32 &&
(color_space)fDisplayMode.space != B_RGBA32)
doubleBuffered = true;
if (doubleBuffered) {
fBackBuffer = new MallocBuffer(fDisplayMode.virtual_width,
fDisplayMode.virtual_height);
status_t ret = fBackBuffer->InitCheck();
if (ret < B_OK) {
delete fBackBuffer;
@ -385,10 +390,11 @@ AccelerantHWInterface::SetMode(const display_mode &mode)
memset(fBackBuffer->Bits(), 255, fBackBuffer->BitsLength());
}
}
return B_OK;
}
void
AccelerantHWInterface::GetMode(display_mode *mode)
{
@ -396,17 +402,18 @@ AccelerantHWInterface::GetMode(display_mode *mode)
*mode = fDisplayMode;
}
status_t
AccelerantHWInterface::UpdateModeList()
{
fModeCount = fAccGetModeCount();
if (fModeCount <= 0)
return B_ERROR;
fModeList = new display_mode[fModeCount];;
fModeList = new display_mode[fModeCount];
if (!fModeList)
return B_NO_MEMORY;
if (fAccGetModeList(fModeList) != B_OK) {
ATRACE(("unable to get mode list\n"));
return B_ERROR;
@ -415,6 +422,7 @@ AccelerantHWInterface::UpdateModeList()
return B_OK;
}
status_t
AccelerantHWInterface::UpdateFrameBufferConfig()
{
@ -422,7 +430,7 @@ AccelerantHWInterface::UpdateFrameBufferConfig()
ATRACE(("unable to get frame buffer config\n"));
return B_ERROR;
}
fFrontBuffer->SetFrameBufferConfig(fFrameBufferConfig);
return B_OK;
}

View File

@ -87,7 +87,7 @@ private:
GetAccelerantHook fAccelerantHook;
engine_token *fEngineToken;
sync_token fSyncToken;
// required hooks - guaranteed to be valid
acquire_engine fAccAcquireEngine;
release_engine fAccReleaseEngine;
@ -96,8 +96,9 @@ private:
get_mode_list fAccGetModeList;
get_frame_buffer_config fAccGetFrameBufferConfig;
set_display_mode fAccSetDisplayMode;
get_display_mode fAccGetDisplayMode;
get_pixel_clock_limits fAccGetPixelClockLimits;
// optional accelerant hooks
get_timing_constraints fAccGetTimingConstraints;
propose_display_mode fAccProposeDisplayMode;

View File

@ -95,24 +95,24 @@ DisplayDriver::Shutdown()
Subclasses must include calls to _SetDepth, _SetHeight, _SetWidth, and _SetMode
to update the state variables kept internally by the DisplayDriver class.
*/
void
status_t
DisplayDriver::SetMode(const display_mode &mode)
{
if (Lock()) {
fDisplayMode = mode;
Unlock();
return B_OK;
}
return B_ERROR;
}
// GetMode
void
DisplayDriver::GetMode(display_mode *mode)
DisplayDriver::GetMode(display_mode &mode)
{
if (!mode)
return;
if (Lock()) {
*mode = fDisplayMode;
mode = fDisplayMode;
Unlock();
}
}

View File

@ -78,6 +78,7 @@ DisplayDriverPainter::Initialize()
fAvailableHWAccleration = fGraphicsCard->AvailableHWAcceleration();
return DisplayDriver::Initialize();
}
return false;
}
@ -1181,19 +1182,24 @@ DisplayDriverPainter::Unlock()
}
// SetMode
void
status_t
DisplayDriverPainter::SetMode(const display_mode &mode)
{
status_t status = B_ERROR;
if (Lock()) {
if (fGraphicsCard->SetMode(mode) >= B_OK) {
status = fGraphicsCard->SetMode(mode);
if (status >= B_OK) {
fPainter->AttachToBuffer(fGraphicsCard->DrawingBuffer());
DisplayDriver::SetMode(mode);
status = DisplayDriver::SetMode(mode);
} else {
fprintf(stderr, "DisplayDriverPainter::SetMode() - unsupported "
"mode!\n");
}
Unlock();
}
return status;
}
// DumpToFile
@ -1282,6 +1288,16 @@ DisplayDriverPainter::GetModeList(display_mode **mode_list, uint32 *count)
return ret;
}
// GetMode
void
DisplayDriverPainter::GetMode(display_mode &mode)
{
if (Lock()) {
fGraphicsCard->GetMode(&mode);
Unlock();
}
}
// GetPixelClockLimits
status_t DisplayDriverPainter::GetPixelClockLimits(display_mode *mode,
uint32 *low,

View File

@ -37,7 +37,7 @@ class HWInterface;
class Painter;
class DisplayDriverPainter : public DisplayDriver {
public:
public:
DisplayDriverPainter();
virtual ~DisplayDriverPainter();
@ -241,7 +241,8 @@ class DisplayDriverPainter : public DisplayDriver {
virtual void Unlock();
// 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 ServerBitmap* DumpToBitmap();