From e5b4782b4ee7663decea60a4385fce3122c2b16d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Thu, 26 May 2005 09:21:51 +0000 Subject: [PATCH] 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 --- headers/private/graphics/vesa/vesa_info.h | 2 - headers/private/servers/app/DisplayDriver.h | 12 +- src/add-ons/accelerants/vesa/mode.cpp | 5 +- .../kernel/drivers/graphics/vesa/device.cpp | 16 +-- .../kernel/drivers/graphics/vesa/vesa.cpp | 40 +++++- src/servers/app/Desktop.cpp | 13 +- src/servers/app/RootLayer.cpp | 124 +++++++++--------- src/servers/app/RootLayer.h | 12 +- src/servers/app/ServerApp.cpp | 2 +- src/servers/app/ServerScreen.cpp | 86 +++++++----- src/servers/app/ServerScreen.h | 32 ++--- .../app/drawing/AccelerantHWInterface.cpp | 62 +++++---- .../app/drawing/AccelerantHWInterface.h | 5 +- src/servers/app/drawing/DisplayDriver.cpp | 12 +- .../app/drawing/DisplayDriverPainter.cpp | 22 +++- .../app/drawing/DisplayDriverPainter.h | 5 +- 16 files changed, 254 insertions(+), 196 deletions(-) diff --git a/headers/private/graphics/vesa/vesa_info.h b/headers/private/graphics/vesa/vesa_info.h index fbfe2c2a63..cf86cd1e9b 100644 --- a/headers/private/graphics/vesa/vesa_info.h +++ b/headers/private/graphics/vesa/vesa_info.h @@ -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; }; diff --git a/headers/private/servers/app/DisplayDriver.h b/headers/private/servers/app/DisplayDriver.h index 5c02e69477..711f3d4455 100644 --- a/headers/private/servers/app/DisplayDriver.h +++ b/headers/private/servers/app/DisplayDriver.h @@ -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; diff --git a/src/add-ons/accelerants/vesa/mode.cpp b/src/add-ons/accelerants/vesa/mode.cpp index 57121b9192..2537cbb0da 100644 --- a/src/add-ons/accelerants/vesa/mode.cpp +++ b/src/add-ons/accelerants/vesa/mode.cpp @@ -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 } diff --git a/src/add-ons/kernel/drivers/graphics/vesa/device.cpp b/src/add-ons/kernel/drivers/graphics/vesa/device.cpp index f56175bab9..22de417a86 100644 --- a/src/add-ons/kernel/drivers/graphics/vesa/device.cpp +++ b/src/add-ons/kernel/drivers/graphics/vesa/device.cpp @@ -11,8 +11,6 @@ #include #include #include -#include -#include #include #include @@ -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); diff --git a/src/add-ons/kernel/drivers/graphics/vesa/vesa.cpp b/src/add-ons/kernel/drivers/graphics/vesa/vesa.cpp index f94b2665bb..0705e68c02 100644 --- a/src/add-ons/kernel/drivers/graphics/vesa/vesa.cpp +++ b/src/add-ons/kernel/drivers/graphics/vesa/vesa.cpp @@ -4,6 +4,9 @@ */ +#include +#include + #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); } diff --git a/src/servers/app/Desktop.cpp b/src/servers/app/Desktop.cpp index 174497ff02..59da593de0 100644 --- a/src/servers/app/Desktop.cpp +++ b/src/servers/app/Desktop.cpp @@ -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(); } diff --git a/src/servers/app/RootLayer.cpp b/src/servers/app/RootLayer.cpp index da5470f366..23836dc05e 100644 --- a/src/servers/app/RootLayer.cpp +++ b/src/servers/app/RootLayer.cpp @@ -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(fScreenPtrList.ItemAt(i)); - - if ( !(screen->SupportsResolution(BPoint(width, height), colorspace)) ) + + for (int i = 0; i < fScreenPtrList.CountItems(); i++) { + Screen *screen = static_cast(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(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(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; iGetDisplayDriver()->GetMode(&mode); + desktop->GetDisplayDriver()->GetMode(mode); // actually this isn't still enough as different workspaces can // have different display_modes diff --git a/src/servers/app/ServerScreen.cpp b/src/servers/app/ServerScreen.cpp index 33478a0230..1ae97de4bc 100644 --- a/src/servers/app/ServerScreen.cpp +++ b/src/servers/app/ServerScreen.cpp @@ -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 +// Axel Dörfler, axeld@pinc-software.de // Description: Handles individual screens -// +// //------------------------------------------------------------------------------ + + #include #include #include + +#include #include #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; } diff --git a/src/servers/app/ServerScreen.h b/src/servers/app/ServerScreen.h index a8e30cf7fe..8a917efa9f 100644 --- a/src/servers/app/ServerScreen.h +++ b/src/servers/app/ServerScreen.h @@ -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 +// Axel Dörfler, axeld@pinc-software.de // Description: Handles individual screens -// +// //------------------------------------------------------------------------------ #ifndef _SCREEN_H_ #define _SCREEN_H_ + #include + 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_ */ diff --git a/src/servers/app/drawing/AccelerantHWInterface.cpp b/src/servers/app/drawing/AccelerantHWInterface.cpp index ce0e1f2dac..6e2c5fa018 100644 --- a/src/servers/app/drawing/AccelerantHWInterface.cpp +++ b/src/servers/app/drawing/AccelerantHWInterface.cpp @@ -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; } diff --git a/src/servers/app/drawing/AccelerantHWInterface.h b/src/servers/app/drawing/AccelerantHWInterface.h index 14eb861d24..06b722b423 100644 --- a/src/servers/app/drawing/AccelerantHWInterface.h +++ b/src/servers/app/drawing/AccelerantHWInterface.h @@ -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; diff --git a/src/servers/app/drawing/DisplayDriver.cpp b/src/servers/app/drawing/DisplayDriver.cpp index 0c52f37d88..3a13a62f31 100644 --- a/src/servers/app/drawing/DisplayDriver.cpp +++ b/src/servers/app/drawing/DisplayDriver.cpp @@ -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(); } } diff --git a/src/servers/app/drawing/DisplayDriverPainter.cpp b/src/servers/app/drawing/DisplayDriverPainter.cpp index 47a1e863dc..c96b321e40 100644 --- a/src/servers/app/drawing/DisplayDriverPainter.cpp +++ b/src/servers/app/drawing/DisplayDriverPainter.cpp @@ -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, diff --git a/src/servers/app/drawing/DisplayDriverPainter.h b/src/servers/app/drawing/DisplayDriverPainter.h index c4e20eebc3..5e1f5206a0 100644 --- a/src/servers/app/drawing/DisplayDriverPainter.h +++ b/src/servers/app/drawing/DisplayDriverPainter.h @@ -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();