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