From a817d6ad5a6b49ed79d84ce2e8a6e9c5f5150560 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Mon, 14 Nov 2005 11:01:02 +0000 Subject: [PATCH] * (tried to) implemented RootLayer::ResizeBy() and activated AS_SET_SCREEN_MODE again; it works in the test environment, but I haven't yet tested it on real hardware. * moved PrivateScreen.h to src/kits/interface/ - it's not used outside of that one. * moved reading the color map from the BPrivateScreen constructor to the ColorMap() method. * improved/cleaned server/client communication for the screen stuff a tiny bit. * fixed the GetBitmap() method I implemented yesterday. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@14908 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/private/interface/PrivateScreen.h | 96 ------- src/kits/interface/PrivateScreen.cpp | 320 +++++++++++----------- src/kits/interface/PrivateScreen.h | 85 ++++++ src/kits/interface/Screen.cpp | 179 ++++++------ src/servers/app/RootLayer.cpp | 22 +- src/servers/app/ServerApp.cpp | 165 ++++++----- 6 files changed, 438 insertions(+), 429 deletions(-) delete mode 100644 headers/private/interface/PrivateScreen.h create mode 100644 src/kits/interface/PrivateScreen.h diff --git a/headers/private/interface/PrivateScreen.h b/headers/private/interface/PrivateScreen.h deleted file mode 100644 index d756d3d06a..0000000000 --- a/headers/private/interface/PrivateScreen.h +++ /dev/null @@ -1,96 +0,0 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2002-2005, Haiku -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// -// File Name: PrivateScreen.h -// Author: Stefano Ceccherini (burton666@libero.it) -// Description: BPrivateScreen is the class which does the real work -// for the proxy class BScreen (it interacts with the app server). -//------------------------------------------------------------------------------ - -#ifndef __PRIVATESCREEN_H -#define __PRIVATESCREEN_H - -#include -#include - -struct screen_desc; -class BApplication; -class BWindow; - -class BPrivateScreen { - // Constructor and destructor are private. Use the static methods - // CheckOut() and Return() instead. -public: - static BPrivateScreen* CheckOut(BWindow *win); - static BPrivateScreen* CheckOut(screen_id id); - static void Return(BPrivateScreen *screen); - - status_t SetToNext(); - - color_space ColorSpace(); - BRect Frame(); - screen_id ID(); - - status_t WaitForRetrace(bigtime_t timeout); - - uint8 IndexForColor(uint8 red, uint8 green, uint8 blue, uint8 alpha); - rgb_color ColorForIndex(const uint8 index); - uint8 InvertIndex(uint8 index); - - const color_map *ColorMap(); - - status_t GetBitmap(BBitmap **bitmap, bool drawCursor, BRect *bound); - status_t ReadBitmap(BBitmap *bitmap, bool drawCursor, BRect *bound); - - rgb_color DesktopColor(uint32 index); - void SetDesktopColor(rgb_color, uint32, bool); - - status_t ProposeMode(display_mode *target, const display_mode *low, const display_mode *high); - - status_t GetModeList(display_mode **mode_list, uint32 *count); - status_t GetMode(uint32 workspace, display_mode *mode); - status_t SetMode(uint32 workspace, display_mode *mode, bool makeDefault); - - status_t GetDeviceInfo(accelerant_device_info *info); - status_t GetPixelClockLimits(display_mode *mode, uint32 *low, uint32 *high); - status_t GetTimingConstraints(display_timing_constraints *dtc); - - status_t SetDPMS(uint32 dpmsState); - uint32 DPMSState(); - uint32 DPMSCapabilites(); - - void* BaseAddress(); - uint32 BytesPerRow(); - - status_t get_screen_desc(screen_desc *desc); - -private: - color_map *fColorMap; - sem_id fRetraceSem; - bool fOwnsColorMap; - - sem_id RetraceSemaphore(); - - BPrivateScreen(); - ~BPrivateScreen(); -}; - -#endif // __PRIVATESCREEN_H diff --git a/src/kits/interface/PrivateScreen.cpp b/src/kits/interface/PrivateScreen.cpp index c20bf7cde6..37ef8f745a 100644 --- a/src/kits/interface/PrivateScreen.cpp +++ b/src/kits/interface/PrivateScreen.cpp @@ -1,33 +1,22 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2002-2005, Haiku -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// -// File Name: PrivateScreen.cpp -// Author: Stefano Ceccherini (burton666@libero.it) -// Description: BPrivateScreen is the class which does the real work -// for the proxy class BScreen (it interacts with the app server). -//------------------------------------------------------------------------------ +/* + * Copyright 2002-2005, Haiku Inc. + * Distributed under the terms of the MIT License. + * + * Authors: + * Stefano Ceccherini (burton666@libero.it) + * Axel Dörfler, axeld@pinc-software.de + */ + +/** BPrivateScreen is the class which does the real work for + * the proxy class BScreen (it interacts with the app server). + */ + + #include "AppServerLink.h" #include "PrivateScreen.h" #include "ServerProtocol.h" +#include #include #include #include @@ -56,35 +45,24 @@ static BLocker sScreenLock("screen lock"); using namespace BPrivate; BPrivateScreen * -BPrivateScreen::CheckOut(BWindow *win) +BPrivateScreen::CheckOut(BWindow *window) { - sScreenLock.Lock(); - - if (sScreen == NULL) { - // TODO: If we start supporting multiple monitors, we - // should return the right screen for the passed BWindow - sScreen = new BPrivateScreen(); - } - - sScreenLock.Unlock(); - - return sScreen; + // TODO: get screen ID from window! + return CheckOut(B_MAIN_SCREEN_ID); } BPrivateScreen * BPrivateScreen::CheckOut(screen_id id) { - sScreenLock.Lock(); - + BAutolock locker(sScreenLock); + if (sScreen == NULL) { // TODO: If we start supporting multiple monitors, we // should return the right object for the given screen_id sScreen = new BPrivateScreen(); } - - sScreenLock.Unlock(); - + return sScreen; } @@ -136,8 +114,8 @@ BPrivateScreen::ID() // TODO: Change this if we start supporting multiple screens return B_MAIN_SCREEN_ID; } - - + + status_t BPrivateScreen::WaitForRetrace(bigtime_t timeout) { @@ -145,7 +123,7 @@ BPrivateScreen::WaitForRetrace(bigtime_t timeout) // we are called. Cache the value then. status_t status; if (fRetraceSem < 0) - fRetraceSem = RetraceSemaphore(); + fRetraceSem = _RetraceSemaphore(); do { status = acquire_sem_etc(fRetraceSem, 1, B_RELATIVE_TIMEOUT, timeout); @@ -159,12 +137,14 @@ uint8 BPrivateScreen::IndexForColor(uint8 red, uint8 green, uint8 blue, uint8 alpha) { // Looks like this check is necessary - if (red == B_TRANSPARENT_COLOR.red && green == B_TRANSPARENT_COLOR.green && - blue == B_TRANSPARENT_COLOR.blue && alpha == B_TRANSPARENT_COLOR.alpha) + if (red == B_TRANSPARENT_COLOR.red + && green == B_TRANSPARENT_COLOR.green + && blue == B_TRANSPARENT_COLOR.blue + && alpha == B_TRANSPARENT_COLOR.alpha) return B_TRANSPARENT_8_BIT; uint16 index = ((blue & 0xf8) << 7) | ((green & 0xf8) << 2) | (red >> 3); - if (fColorMap) + if (ColorMap()) return fColorMap->index_map[index]; return 0; @@ -174,7 +154,7 @@ BPrivateScreen::IndexForColor(uint8 red, uint8 green, uint8 blue, uint8 alpha) rgb_color BPrivateScreen::ColorForIndex(const uint8 index) { - if (fColorMap) + if (ColorMap()) return fColorMap->color_list[index]; return rgb_color(); @@ -184,7 +164,7 @@ BPrivateScreen::ColorForIndex(const uint8 index) uint8 BPrivateScreen::InvertIndex(uint8 index) { - if (fColorMap) + if (ColorMap()) return fColorMap->inversion_map[index]; return 0; @@ -194,6 +174,29 @@ BPrivateScreen::InvertIndex(uint8 index) const color_map * BPrivateScreen::ColorMap() { + if (fColorMap == NULL) { + BAutolock locker(sScreenLock); + + if (fColorMap != NULL) { + // someone could have been faster than us + return fColorMap; + } + + // TODO: BeOS R5 here gets the colormap pointer + // (with BApplication::ro_offset_to_ptr() ?) + // which is contained in a shared area created by the server. + BPrivate::AppServerLink link; + link.StartMessage(AS_SCREEN_GET_COLORMAP); + link.Attach(ID()); + + status_t status; + if (link.FlushWithReply(status) == B_OK && status == B_OK) { + fColorMap = (color_map *)malloc(sizeof(color_map)); + fOwnsColorMap = true; + link.Read(fColorMap); + } + } + return fColorMap; } @@ -204,13 +207,19 @@ BPrivateScreen::GetBitmap(BBitmap **_bitmap, bool drawCursor, BRect *bounds) if (_bitmap == NULL) return B_BAD_VALUE; - BBitmap* bitmap = new (std::nothrow) BBitmap(Frame(), ColorSpace()); + BRect rect; + if (bounds != NULL) + rect = *bounds; + else + rect = Frame(); + + BBitmap* bitmap = new (std::nothrow) BBitmap(rect, ColorSpace()); if (bitmap == NULL) return B_NO_MEMORY; status_t status = bitmap->InitCheck(); if (status == B_OK) - status = ReadBitmap(bitmap, drawCursor, bounds); + status = ReadBitmap(bitmap, drawCursor, &rect); if (status != B_OK) { delete bitmap; return status; @@ -222,27 +231,27 @@ BPrivateScreen::GetBitmap(BBitmap **_bitmap, bool drawCursor, BRect *bounds) status_t -BPrivateScreen::ReadBitmap(BBitmap *bitmap, bool drawCursor, BRect *bound) +BPrivateScreen::ReadBitmap(BBitmap *bitmap, bool drawCursor, BRect *bounds) { if (bitmap == NULL) return B_BAD_VALUE; - + BRect rect; - if (bound != NULL) - rect = *bound; + if (bounds != NULL) + rect = *bounds; else rect = Frame(); - + BPrivate::AppServerLink link; link.StartMessage(AS_READ_BITMAP); link.Attach(bitmap->get_server_token()); link.Attach(drawCursor); link.Attach(rect); - - int32 code; - if (link.FlushWithReply(code) < B_OK || code != SERVER_TRUE) - return B_ERROR; - + + status_t status = B_ERROR; + if (link.FlushWithReply(status) < B_OK || status != B_OK) + return status; + return B_OK; } @@ -258,7 +267,7 @@ BPrivateScreen::DesktopColor(uint32 workspace) int32 code; if (link.FlushWithReply(code) == B_OK - && code == SERVER_TRUE) + && code == B_OK) link.Read(&color); return color; @@ -266,7 +275,8 @@ BPrivateScreen::DesktopColor(uint32 workspace) void -BPrivateScreen::SetDesktopColor(rgb_color color, uint32 workspace, bool makeDefault) +BPrivateScreen::SetDesktopColor(rgb_color color, uint32 workspace, + bool makeDefault) { BPrivate::AppServerLink link; @@ -280,53 +290,57 @@ BPrivateScreen::SetDesktopColor(rgb_color color, uint32 workspace, bool makeDefa status_t BPrivateScreen::ProposeMode(display_mode *target, - const display_mode *low, const display_mode *high) + const display_mode *low, const display_mode *high) { // We can't return B_BAD_VALUE here, because it's used to indicate // that the mode returned is supported, but it doesn't fall // within the limit (see ProposeMode() documentation) if (target == NULL || low == NULL || high == NULL) return B_ERROR; - + BPrivate::AppServerLink link; link.StartMessage(AS_PROPOSE_MODE); link.Attach(ID()); link.Attach(*target); link.Attach(*low); link.Attach(*high); - - int32 reply; + status_t status = B_ERROR; - if (link.FlushWithReply(reply) == B_OK && reply == SERVER_TRUE) { - link.Read(target); - // The status is important here. See documentation - link.Read(&status); + if (link.FlushWithReply(status) == B_OK && status == B_OK) { + link.Read(target); + + bool withinLimits; + link.Read(&withinLimits); + if (!withinLimits) + status = B_BAD_VALUE; } - + return status; } status_t -BPrivateScreen::GetModeList(display_mode **modeList, uint32 *count) +BPrivateScreen::GetModeList(display_mode **_modeList, uint32 *_count) { - if (modeList == NULL || count == NULL) + if (_modeList == NULL || _count == NULL) return B_BAD_VALUE; - - status_t status = B_ERROR; + BPrivate::AppServerLink link; link.StartMessage(AS_GET_MODE_LIST); link.Attach(ID()); - int32 reply; - if (link.FlushWithReply(reply) == B_OK && reply == SERVER_TRUE) { - link.Read(count); - int32 size = *count * sizeof(display_mode); - *modeList = (display_mode *)malloc(size); - link.Read(*modeList, size); - // TODO: get status from app_server - status = B_OK; + + status_t status = B_ERROR; + if (link.FlushWithReply(status) == B_OK && status == B_OK) { + link.Read(_count); + // TODO: this could get too big for the link + int32 size = *_count * sizeof(display_mode); + *_modeList = (display_mode *)malloc(size); + if (_modeList == NULL) + return B_NO_MEMORY; + + link.Read(*_modeList, size); } - + return status; } @@ -336,26 +350,19 @@ BPrivateScreen::GetMode(uint32 workspace, display_mode *mode) { if (mode == NULL) return B_BAD_VALUE; - + BPrivate::AppServerLink link; link.StartMessage(AS_SCREEN_GET_MODE); link.Attach(ID()); link.Attach(workspace); - int32 code; - if (link.FlushWithReply(code) != B_OK - || code != SERVER_TRUE) - return B_ERROR; - - display_mode currentMode; - link.Read(¤tMode); - status_t status = B_ERROR; - link.Read(&status); - if (status == B_OK && mode) - *mode = currentMode; - - return status; + if (link.FlushWithReply(status) != B_OK + || status != B_OK) + return status; + + link.Read(mode); + return B_OK; } @@ -364,18 +371,16 @@ BPrivateScreen::SetMode(uint32 workspace, display_mode *mode, bool makeDefault) { if (mode == NULL) return B_BAD_VALUE; - + BPrivate::AppServerLink link; link.StartMessage(AS_SCREEN_SET_MODE); link.Attach(ID()); link.Attach(workspace); link.Attach(*mode); link.Attach(makeDefault); - + status_t status = B_ERROR; - int32 code; - if (link.FlushWithReply(code) == B_OK && code == SERVER_TRUE) - link.Read(&status); + link.FlushWithReply(status); return status; } @@ -386,17 +391,18 @@ BPrivateScreen::GetDeviceInfo(accelerant_device_info *info) { if (info == NULL) return B_BAD_VALUE; - + BPrivate::AppServerLink link; link.StartMessage(AS_GET_ACCELERANT_INFO); link.Attach(ID()); - int32 code; - if (link.FlushWithReply(code) == B_OK && code == SERVER_TRUE) { + + status_t status = B_ERROR; + if (link.FlushWithReply(status) == B_OK && status == B_OK) { link.Read(info); return B_OK; } - - return B_ERROR; + + return status; } @@ -405,41 +411,40 @@ BPrivateScreen::GetPixelClockLimits(display_mode *mode, uint32 *low, uint32 *hig { if (mode == NULL || low == NULL || high == NULL) return B_BAD_VALUE; - + BPrivate::AppServerLink link; link.StartMessage(AS_GET_PIXEL_CLOCK_LIMITS); link.Attach(ID()); link.Attach(*mode); - - int32 code; - if (link.FlushWithReply(code) == B_OK && code == SERVER_TRUE) { + + status_t status; + if (link.FlushWithReply(status) == B_OK && status == B_OK) { link.Read(low); link.Read(high); - return B_OK; } - - return B_ERROR; + + return status; } status_t -BPrivateScreen::GetTimingConstraints(display_timing_constraints *dtc) +BPrivateScreen::GetTimingConstraints(display_timing_constraints *constraints) { - if (dtc == NULL) + if (constraints == NULL) return B_BAD_VALUE; - + BPrivate::AppServerLink link; link.StartMessage(AS_GET_TIMING_CONSTRAINTS); link.Attach(ID()); - - int32 code; - if (link.FlushWithReply(code) == B_OK && code == SERVER_TRUE) { - link.Read(dtc); + + status_t status = B_ERROR; + if (link.FlushWithReply(status) == B_OK && status == B_OK) { + link.Read(constraints); return B_OK; } - - return B_ERROR; + + return status; } @@ -450,11 +455,11 @@ BPrivateScreen::SetDPMS(uint32 dpmsState) link.StartMessage(AS_SET_DPMS); link.Attach(ID()); link.Attach(dpmsState); - int32 reply; - if (link.FlushWithReply(reply) == B_OK && reply == SERVER_TRUE) - return B_OK; - - return B_ERROR; + + status_t status = B_ERROR; + link.FlushWithReply(status); + + return status; } @@ -462,14 +467,15 @@ uint32 BPrivateScreen::DPMSState() { uint32 state = 0; - + BPrivate::AppServerLink link; link.StartMessage(AS_GET_DPMS_STATE); link.Attach(ID()); - int32 reply; - if (link.FlushWithReply(reply) == B_OK && reply == SERVER_TRUE) + + status_t status; + if (link.FlushWithReply(status) == B_OK && status == B_OK) link.Read(&state); - + return state; } @@ -478,14 +484,15 @@ uint32 BPrivateScreen::DPMSCapabilites() { uint32 capabilities = 0; - + BPrivate::AppServerLink link; link.StartMessage(AS_GET_DPMS_CAPABILITIES); link.Attach(ID()); - int32 reply; - if (link.FlushWithReply(reply) == B_OK && reply == SERVER_TRUE) + + status_t status; + if (link.FlushWithReply(status) == B_OK && status == B_OK) link.Read(&capabilities); - + return capabilities; } @@ -496,7 +503,7 @@ BPrivateScreen::BaseAddress() screen_desc desc; if (get_screen_desc(&desc) == B_OK) return desc.base_address; - + return NULL; } @@ -507,6 +514,7 @@ BPrivateScreen::BytesPerRow() screen_desc desc; if (get_screen_desc(&desc) == B_OK) return desc.bytes_per_row; + return 0; } @@ -528,20 +536,19 @@ BPrivateScreen::get_screen_desc(screen_desc *desc) } -// private methods +// #pragma mark - private methods + + sem_id -BPrivateScreen::RetraceSemaphore() +BPrivateScreen::_RetraceSemaphore() { - sem_id id = B_BAD_SEM_ID; - BPrivate::AppServerLink link; link.StartMessage(AS_GET_RETRACE_SEMAPHORE); link.Attach(ID()); - int32 reply; - if (link.FlushWithReply(reply) == B_OK - && reply == SERVER_TRUE) - link.Read(&id); - + + sem_id id = B_BAD_SEM_ID; + link.FlushWithReply(id); + return id; } @@ -552,19 +559,6 @@ BPrivateScreen::BPrivateScreen() fRetraceSem(-1), fOwnsColorMap(false) { - // TODO: BeOS R5 here gets the colormap pointer - // (with BApplication::ro_offset_to_ptr() ?) - // which is contained in a shared area created by the server. - BPrivate::AppServerLink link; - link.StartMessage(AS_SCREEN_GET_COLORMAP); - link.Attach(ID()); - - int32 reply; - if (link.FlushWithReply(reply) == B_OK && reply == SERVER_TRUE) { - fColorMap = (color_map *)malloc(sizeof(color_map)); - fOwnsColorMap = true; - link.Read(fColorMap); - } } diff --git a/src/kits/interface/PrivateScreen.h b/src/kits/interface/PrivateScreen.h new file mode 100644 index 0000000000..5e19b584bc --- /dev/null +++ b/src/kits/interface/PrivateScreen.h @@ -0,0 +1,85 @@ +/* + * Copyright 2002-2005, Haiku Inc. + * Distributed under the terms of the MIT License. + * + * Authors: + * Stefano Ceccherini (burton666@libero.it) + * Axel Dörfler, axeld@pinc-software.de + */ +#ifndef _PRIVATE_SCREEN_H_ +#define _PRIVATE_SCREEN_H_ + + +#include +#include + +struct screen_desc; +struct color_map; +struct display_mode; +struct display_timing_constraints; +class BBitmap; +class BApplication; +class BWindow; + + +class BPrivateScreen { + // Constructor and destructor are private. Use the static methods + // CheckOut() and Return() instead. + public: + static BPrivateScreen* CheckOut(BWindow *window); + static BPrivateScreen* CheckOut(screen_id id); + static void Return(BPrivateScreen *screen); + + status_t SetToNext(); + + color_space ColorSpace(); + BRect Frame(); + screen_id ID(); + + status_t WaitForRetrace(bigtime_t timeout); + + uint8 IndexForColor(uint8 red, uint8 green, uint8 blue, uint8 alpha); + rgb_color ColorForIndex(const uint8 index); + uint8 InvertIndex(uint8 index); + + const color_map *ColorMap(); + + status_t GetBitmap(BBitmap **bitmap, bool drawCursor, BRect *bounds); + status_t ReadBitmap(BBitmap *bitmap, bool drawCursor, BRect *bounds); + + rgb_color DesktopColor(uint32 index); + void SetDesktopColor(rgb_color, uint32, bool); + + status_t ProposeMode(display_mode *target, const display_mode *low, + const display_mode *high); + + status_t GetModeList(display_mode **_modeList, uint32 *_count); + status_t GetMode(uint32 workspace, display_mode *mode); + status_t SetMode(uint32 workspace, display_mode *mode, bool makeDefault); + + status_t GetDeviceInfo(accelerant_device_info *info); + status_t GetPixelClockLimits(display_mode *mode, uint32 *low, uint32 *high); + status_t GetTimingConstraints(display_timing_constraints *constraints); + + status_t SetDPMS(uint32 dpmsState); + uint32 DPMSState(); + uint32 DPMSCapabilites(); + + void* BaseAddress(); + uint32 BytesPerRow(); + + status_t get_screen_desc(screen_desc *desc); + + private: + BPrivateScreen(); + ~BPrivateScreen(); + + sem_id _RetraceSemaphore(); + + private: + color_map *fColorMap; + sem_id fRetraceSem; + bool fOwnsColorMap; +}; + +#endif // _PRIVATE_SCREEN_H_ diff --git a/src/kits/interface/Screen.cpp b/src/kits/interface/Screen.cpp index f65db0a69b..52ce62f7cc 100644 --- a/src/kits/interface/Screen.cpp +++ b/src/kits/interface/Screen.cpp @@ -1,33 +1,20 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2003-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"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// -// File Name: Screen.cpp -// Author: Stefano Ceccherini (burton666@libero.it) -// Description: BScreen lets you retrieve and change the display settings. -//------------------------------------------------------------------------------ +/* + * Copyright 2003-2005, Haiku Inc. + * Distributed under the terms of the MIT License. + * + * Authors: + * Stefano Ceccherini (burton666@libero.it) + * Axel Dörfler, axeld@pinc-software.de + */ + +/** BScreen lets you retrieve and change the display settings. */ + + +#include "PrivateScreen.h" + #include #include -#include - /*! \brief Creates a BScreen object which represents the display with the given screen_id \param id The screen_id of the screen to get. @@ -37,17 +24,17 @@ */ BScreen::BScreen(screen_id id) { - screen = BPrivateScreen::CheckOut(id); + fScreen = BPrivateScreen::CheckOut(id); } /*! \brief Creates a BScreen object which represents the display which contains the given BWindow. - \param win A BWindow. + \param window A BWindow. */ -BScreen::BScreen(BWindow *win) +BScreen::BScreen(BWindow *window) { - screen = BPrivateScreen::CheckOut(win); + fScreen = BPrivateScreen::CheckOut(window); } @@ -55,8 +42,8 @@ BScreen::BScreen(BWindow *win) */ BScreen::~BScreen() { - if (screen != NULL) - BPrivateScreen::Return(screen); + if (fScreen != NULL) + BPrivateScreen::Return(fScreen); } @@ -66,7 +53,7 @@ BScreen::~BScreen() bool BScreen::IsValid() { - return (screen != NULL); + return fScreen != NULL; } @@ -76,8 +63,8 @@ BScreen::IsValid() status_t BScreen::SetToNext() { - if (screen != NULL) - return screen->SetToNext(); + if (fScreen != NULL) + return fScreen->SetToNext(); return B_ERROR; } @@ -89,8 +76,8 @@ BScreen::SetToNext() color_space BScreen::ColorSpace() { - if (screen != NULL) - return screen->ColorSpace(); + if (fScreen != NULL) + return fScreen->ColorSpace(); return B_NO_COLOR_SPACE; } @@ -101,8 +88,8 @@ BScreen::ColorSpace() BRect BScreen::Frame() { - if (screen != NULL) - return screen->Frame(); + if (fScreen != NULL) + return fScreen->Frame(); return BRect(0, 0, 0, 0); } @@ -116,8 +103,8 @@ BScreen::Frame() screen_id BScreen::ID() { - if (screen != NULL) - return screen->ID(); + if (fScreen != NULL) + return fScreen->ID(); return B_MAIN_SCREEN_ID; } @@ -128,8 +115,8 @@ BScreen::ID() status_t BScreen::WaitForRetrace() { - if (screen != NULL) - return screen->WaitForRetrace(B_INFINITE_TIMEOUT); + if (fScreen != NULL) + return fScreen->WaitForRetrace(B_INFINITE_TIMEOUT); return B_ERROR; } @@ -143,8 +130,8 @@ BScreen::WaitForRetrace() status_t BScreen::WaitForRetrace(bigtime_t timeout) { - if (screen != NULL) - return screen->WaitForRetrace(timeout); + if (fScreen != NULL) + return fScreen->WaitForRetrace(timeout); return B_ERROR; } @@ -160,8 +147,8 @@ BScreen::WaitForRetrace(bigtime_t timeout) uint8 BScreen::IndexForColor(uint8 r, uint8 g, uint8 b, uint8 a) { - if (screen != NULL) - return screen->IndexForColor(r, g, b, a); + if (fScreen != NULL) + return fScreen->IndexForColor(r, g, b, a); return 0; } @@ -173,8 +160,8 @@ BScreen::IndexForColor(uint8 r, uint8 g, uint8 b, uint8 a) rgb_color BScreen::ColorForIndex(const uint8 index) { - if (screen != NULL) - return screen->ColorForIndex(index); + if (fScreen != NULL) + return fScreen->ColorForIndex(index); return rgb_color(); } @@ -186,8 +173,8 @@ BScreen::ColorForIndex(const uint8 index) uint8 BScreen::InvertIndex(uint8 index) { - if (screen != NULL) - return screen->InvertIndex(index); + if (fScreen != NULL) + return fScreen->InvertIndex(index); return 0; } @@ -198,8 +185,8 @@ BScreen::InvertIndex(uint8 index) const color_map* BScreen::ColorMap() { - if (screen != NULL) - return screen->ColorMap(); + if (fScreen != NULL) + return fScreen->ColorMap(); return NULL; } @@ -213,8 +200,8 @@ BScreen::ColorMap() status_t BScreen::GetBitmap(BBitmap **screen_shot, bool draw_cursor, BRect *bound) { - if (screen != NULL) - return screen->GetBitmap(screen_shot, draw_cursor, bound); + if (fScreen != NULL) + return fScreen->GetBitmap(screen_shot, draw_cursor, bound); return B_ERROR; } @@ -231,8 +218,8 @@ BScreen::GetBitmap(BBitmap **screen_shot, bool draw_cursor, BRect *bound) status_t BScreen::ReadBitmap(BBitmap *buffer, bool draw_cursor, BRect *bound) { - if (screen != NULL) - return screen->ReadBitmap(buffer, draw_cursor, bound); + if (fScreen != NULL) + return fScreen->ReadBitmap(buffer, draw_cursor, bound); return B_ERROR; } @@ -243,8 +230,9 @@ BScreen::ReadBitmap(BBitmap *buffer, bool draw_cursor, BRect *bound) rgb_color BScreen::DesktopColor() { - if (screen != NULL) - return screen->DesktopColor(B_ALL_WORKSPACES); + if (fScreen != NULL) + return fScreen->DesktopColor(B_ALL_WORKSPACES); + return rgb_color(); } @@ -256,8 +244,9 @@ BScreen::DesktopColor() rgb_color BScreen::DesktopColor(uint32 workspace) { - if (screen != NULL) - return screen->DesktopColor(workspace); + if (fScreen != NULL) + return fScreen->DesktopColor(workspace); + return rgb_color(); } @@ -269,8 +258,8 @@ BScreen::DesktopColor(uint32 workspace) void BScreen::SetDesktopColor(rgb_color rgb, bool stick) { - if (screen != NULL) - screen->SetDesktopColor(rgb, B_ALL_WORKSPACES, stick); + if (fScreen != NULL) + fScreen->SetDesktopColor(rgb, B_ALL_WORKSPACES, stick); } @@ -282,8 +271,8 @@ BScreen::SetDesktopColor(rgb_color rgb, bool stick) void BScreen::SetDesktopColor(rgb_color rgb, uint32 index, bool stick) { - if (screen != NULL) - screen->SetDesktopColor(rgb, index, stick); + if (fScreen != NULL) + fScreen->SetDesktopColor(rgb, index, stick); } @@ -299,8 +288,8 @@ BScreen::SetDesktopColor(rgb_color rgb, uint32 index, bool stick) status_t BScreen::ProposeMode(display_mode *target, const display_mode *low, const display_mode *high) { - if (screen != NULL) - return screen->ProposeMode(target, low, high); + if (fScreen != NULL) + return fScreen->ProposeMode(target, low, high); return B_ERROR; } @@ -316,8 +305,8 @@ BScreen::ProposeMode(display_mode *target, const display_mode *low, const displa status_t BScreen::GetModeList(display_mode **mode_list, uint32 *count) { - if (screen != NULL) - return screen->GetModeList(mode_list, count); + if (fScreen != NULL) + return fScreen->GetModeList(mode_list, count); return B_ERROR; } @@ -330,8 +319,8 @@ BScreen::GetModeList(display_mode **mode_list, uint32 *count) status_t BScreen::GetMode(display_mode *mode) { - if (screen != NULL) - return screen->GetMode(B_ALL_WORKSPACES, mode); + if (fScreen != NULL) + return fScreen->GetMode(B_ALL_WORKSPACES, mode); return B_ERROR; } @@ -344,8 +333,8 @@ BScreen::GetMode(display_mode *mode) status_t BScreen::GetMode(uint32 workspace, display_mode *mode) { - if (screen != NULL) - return screen->GetMode(workspace, mode); + if (fScreen != NULL) + return fScreen->GetMode(workspace, mode); return B_ERROR; } @@ -358,8 +347,8 @@ BScreen::GetMode(uint32 workspace, display_mode *mode) status_t BScreen::SetMode(display_mode *mode, bool makeDefault) { - if (screen != NULL) - return screen->SetMode(B_ALL_WORKSPACES, mode, makeDefault); + if (fScreen != NULL) + return fScreen->SetMode(B_ALL_WORKSPACES, mode, makeDefault); return B_ERROR; } @@ -373,8 +362,8 @@ BScreen::SetMode(display_mode *mode, bool makeDefault) status_t BScreen::SetMode(uint32 workspace, display_mode *mode, bool makeDefault) { - if (screen != NULL) - return screen->SetMode(workspace, mode, makeDefault); + if (fScreen != NULL) + return fScreen->SetMode(workspace, mode, makeDefault); return B_ERROR; } @@ -386,8 +375,8 @@ BScreen::SetMode(uint32 workspace, display_mode *mode, bool makeDefault) status_t BScreen::GetDeviceInfo(accelerant_device_info *info) { - if (screen != NULL) - return screen->GetDeviceInfo(info); + if (fScreen != NULL) + return fScreen->GetDeviceInfo(info); return B_ERROR; } @@ -402,8 +391,8 @@ BScreen::GetDeviceInfo(accelerant_device_info *info) status_t BScreen::GetPixelClockLimits(display_mode *mode, uint32 *low, uint32 *high) { - if (screen != NULL) - return screen->GetPixelClockLimits(mode, low, high); + if (fScreen != NULL) + return fScreen->GetPixelClockLimits(mode, low, high); return B_ERROR; } @@ -416,8 +405,8 @@ BScreen::GetPixelClockLimits(display_mode *mode, uint32 *low, uint32 *high) status_t BScreen::GetTimingConstraints(display_timing_constraints *dtc) { - if (screen != NULL) - return screen->GetTimingConstraints(dtc); + if (fScreen != NULL) + return fScreen->GetTimingConstraints(dtc); return B_ERROR; } @@ -434,8 +423,8 @@ BScreen::GetTimingConstraints(display_timing_constraints *dtc) status_t BScreen::SetDPMS(uint32 dpms_state) { - if (screen != NULL) - return screen->SetDPMS(dpms_state); + if (fScreen != NULL) + return fScreen->SetDPMS(dpms_state); return B_ERROR; } @@ -445,8 +434,8 @@ BScreen::SetDPMS(uint32 dpms_state) uint32 BScreen::DPMSState() { - if (screen != NULL) - return screen->DPMSState(); + if (fScreen != NULL) + return fScreen->DPMSState(); return B_ERROR; } @@ -456,8 +445,8 @@ BScreen::DPMSState() uint32 BScreen::DPMSCapabilites() { - if (screen != NULL) - return screen->DPMSCapabilites(); + if (fScreen != NULL) + return fScreen->DPMSCapabilites(); return B_ERROR; } @@ -468,7 +457,7 @@ BScreen::DPMSCapabilites() BPrivateScreen* BScreen::private_screen() { - return screen; + return fScreen; } @@ -503,8 +492,8 @@ BScreen::BScreen(const BScreen &screen) void* BScreen::BaseAddress() { - if (screen != NULL) - return screen->BaseAddress(); + if (fScreen != NULL) + return fScreen->BaseAddress(); return NULL; } @@ -514,7 +503,7 @@ BScreen::BaseAddress() uint32 BScreen::BytesPerRow() { - if (screen != NULL) - return screen->BytesPerRow(); + if (fScreen != NULL) + return fScreen->BytesPerRow(); return 0; } diff --git a/src/servers/app/RootLayer.cpp b/src/servers/app/RootLayer.cpp index 987e075cc1..a495ebbe39 100644 --- a/src/servers/app/RootLayer.cpp +++ b/src/servers/app/RootLayer.cpp @@ -295,7 +295,27 @@ RootLayer::MoveBy(float x, float y) void RootLayer::ResizeBy(float x, float y) { - // TODO: implement + if (x == 0 && y == 0) + return; + + // TODO: we should be able to update less here + + //BRect previous = fFrame; + + fFrame.right += x; + fFrame.bottom += y; + + fFullVisible2.Set(Bounds()); + fVisible2.Set(Bounds()); + + BRegion region(fFrame); + MarkForRebuild(region); + TriggerRebuild(); + + //region.Exclude(previous); + + MarkForRedraw(region); + TriggerRedraw(); } diff --git a/src/servers/app/ServerApp.cpp b/src/servers/app/ServerApp.cpp index 0307377a3f..fdaa6a078d 100644 --- a/src/servers/app/ServerApp.cpp +++ b/src/servers/app/ServerApp.cpp @@ -2000,9 +2000,8 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link) // actually this isn't still enough as different workspaces can // have different display_modes - fLink.StartMessage(SERVER_TRUE); + fLink.StartMessage(B_OK); fLink.Attach(mode); - fLink.Attach(B_OK); fLink.Flush(); break; } @@ -2030,11 +2029,17 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link) // TODO: lock RootLayer, set mode and tell it to update it's frame and all clipping // optionally put this into a message and let the root layer thread handle it. -// status_t ret = fDesktop->ScreenAt(0)->SetMode(mode); - status_t ret = B_ERROR; + RootLayer* rootLayer = fDesktop->ActiveRootLayer(); + rootLayer->Lock(); + status_t status = fDesktop->ScreenAt(0)->SetMode(mode); + if (status == B_OK) { + BRect bounds = rootLayer->Bounds(); + rootLayer->ResizeBy(mode.virtual_width - 1 - bounds.Width(), + mode.virtual_height - 1 - bounds.Height()); + } + rootLayer->Unlock(); - fLink.StartMessage(SERVER_TRUE); - fLink.Attach(ret); + fLink.StartMessage(status); fLink.Flush(); break; } @@ -2050,16 +2055,20 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link) link.Read(&low); link.Read(&high); status_t status = fDesktop->GetHWInterface()->ProposeMode(&target, &low, &high); - // TODO: We always return SERVER_TRUE and put the real - // error code in the message. FIX this. - fLink.StartMessage(SERVER_TRUE); - fLink.Attach(target); - fLink.Attach(status); + + // ProposeMode() returns B_BAD_VALUE to hint that the candidate is + // not within the given limits (but is supported) + if (status == B_OK || status == B_BAD_VALUE) { + fLink.StartMessage(B_OK); + fLink.Attach(target); + fLink.Attach(status == B_OK); + } else + fLink.StartMessage(status); + fLink.Flush(); - break; } - + case AS_GET_MODE_LIST: { screen_id id; @@ -2068,14 +2077,15 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link) display_mode* modeList; uint32 count; - if (fDesktop->GetHWInterface()->GetModeList(&modeList, &count) == B_OK) { - fLink.StartMessage(SERVER_TRUE); + status_t status = fDesktop->GetHWInterface()->GetModeList(&modeList, &count); + if (status == B_OK) { + fLink.StartMessage(B_OK); fLink.Attach(count); fLink.Attach(modeList, sizeof(display_mode) * count); delete[] modeList; } else - fLink.StartMessage(SERVER_FALSE); + fLink.StartMessage(status); fLink.Flush(); break; @@ -2087,14 +2097,14 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link) screen_id id; link.Read(&id); - + const color_map *colorMap = SystemColorMap(); if (colorMap != NULL) { - fLink.StartMessage(SERVER_TRUE); + fLink.StartMessage(B_OK); fLink.Attach(*colorMap); } else - fLink.StartMessage(SERVER_FALSE); - + fLink.StartMessage(B_ERROR); + fLink.Flush(); break; } @@ -2103,82 +2113,89 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link) { STRACE(("ServerApp %s: get desktop color\n", Signature())); - uint32 workspaceIndex = 0; + uint32 workspaceIndex; link.Read(&workspaceIndex); - // ToDo: for some reason, we currently get "1" as no. of workspace - workspaceIndex = 0; - // ToDo: locking is probably wrong - why the hell is there no (safe) // way to get to the workspace object directly? RootLayer *root = fDesktop->ActiveRootLayer(); root->Lock(); - Workspace *workspace = root->WorkspaceAt(workspaceIndex); + Workspace *workspace; + + // we're nice to our children (and also take the default case + // into account which asks for the current workspace) + if (workspaceIndex > (uint32)root->WorkspaceCount()) + workspace = root->ActiveWorkspace(); + else + workspace = root->WorkspaceAt(workspaceIndex); + if (workspace != NULL) { - fLink.StartMessage(SERVER_TRUE); + fLink.StartMessage(B_OK); fLink.Attach(workspace->BGColor().GetColor32()); } else - fLink.StartMessage(SERVER_FALSE); + fLink.StartMessage(B_ERROR); fLink.Flush(); root->Unlock(); break; } - + case AS_GET_ACCELERANT_INFO: { STRACE(("ServerApp %s: get accelerant info\n", Signature())); - + // We aren't using the screen_id for now... screen_id id; link.Read(&id); - + accelerant_device_info accelerantInfo; // TODO: I wonder if there should be a "desktop" lock... - if (fDesktop->GetHWInterface()->GetDeviceInfo(&accelerantInfo) == B_OK) { - fLink.StartMessage(SERVER_TRUE); + status_t status = fDesktop->GetHWInterface()->GetDeviceInfo(&accelerantInfo); + if (status == B_OK) { + fLink.StartMessage(B_OK); fLink.Attach(accelerantInfo); } else - fLink.StartMessage(SERVER_FALSE); - + fLink.StartMessage(status); + fLink.Flush(); break; } - + case AS_GET_RETRACE_SEMAPHORE: { STRACE(("ServerApp %s: get retrace semaphore\n", Signature())); - + // We aren't using the screen_id for now... screen_id id; link.Read(&id); - + sem_id semaphore = fDesktop->GetHWInterface()->RetraceSemaphore(); - fLink.StartMessage(SERVER_TRUE); - fLink.Attach(semaphore); + fLink.StartMessage(semaphore); fLink.Flush(); break; } - + case AS_GET_TIMING_CONSTRAINTS: { STRACE(("ServerApp %s: get timing constraints\n", Signature())); // We aren't using the screen_id for now... screen_id id; link.Read(&id); - + display_timing_constraints constraints; - if (fDesktop->GetHWInterface()->GetTimingConstraints(&constraints) == B_OK) { - fLink.StartMessage(SERVER_TRUE); + status_t status = fDesktop->GetHWInterface()->GetTimingConstraints( + &constraints); + if (status == B_OK) { + fLink.StartMessage(B_OK); fLink.Attach(constraints); } else - fLink.StartMessage(SERVER_FALSE); - + fLink.StartMessage(status); + fLink.Flush(); break; } - + case AS_GET_PIXEL_CLOCK_LIMITS: { STRACE(("ServerApp %s: get pixel clock limits\n", Signature())); @@ -2187,87 +2204,87 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link) link.Read(&id); display_mode mode; link.Read(&mode); - + uint32 low, high; - if (fDesktop->GetHWInterface()->GetPixelClockLimits(&mode, &low, &high) == B_OK) { - fLink.StartMessage(SERVER_TRUE); + status_t status = fDesktop->GetHWInterface()->GetPixelClockLimits(&mode, + &low, &high); + if (status == B_OK) { + fLink.StartMessage(B_OK); fLink.Attach(low); fLink.Attach(high); } else - fLink.StartMessage(SERVER_FALSE); - + fLink.StartMessage(status); + fLink.Flush(); break; } - + case AS_SET_DPMS: { STRACE(("ServerApp %s: AS_SET_DPMS\n", Signature())); screen_id id; link.Read(&id); - + uint32 mode; link.Read(&mode); - - if (fDesktop->GetHWInterface()->SetDPMSMode(mode) == B_OK) - fLink.StartMessage(SERVER_TRUE); - else - fLink.StartMessage(SERVER_FALSE); - + + status_t status = fDesktop->GetHWInterface()->SetDPMSMode(mode); + fLink.StartMessage(status); + fLink.Flush(); break; } - + case AS_GET_DPMS_STATE: { STRACE(("ServerApp %s: AS_GET_DPMS_STATE\n", Signature())); - + screen_id id; link.Read(&id); - + uint32 state = fDesktop->GetHWInterface()->DPMSMode(); - fLink.StartMessage(SERVER_TRUE); + fLink.StartMessage(B_OK); fLink.Attach(state); fLink.Flush(); break; } - + case AS_GET_DPMS_CAPABILITIES: { STRACE(("ServerApp %s: AS_GET_DPMS_CAPABILITIES\n", Signature())); screen_id id; link.Read(&id); - + uint32 capabilities = fDesktop->GetHWInterface()->DPMSCapabilities(); - fLink.StartMessage(SERVER_TRUE); + fLink.StartMessage(B_OK); fLink.Attach(capabilities); fLink.Flush(); break; } - + case AS_READ_BITMAP: { STRACE(("ServerApp %s: AS_READ_BITMAP\n", Signature())); int32 bitmapToken; link.Read(&bitmapToken); - + bool drawCursor = true; link.Read(&drawCursor); - + BRect bounds; link.Read(&bounds); - + ServerBitmap *bitmap = FindBitmap(bitmapToken); if (bitmap != NULL) { - fLink.StartMessage(SERVER_TRUE); + fLink.StartMessage(B_OK); // TODO: Implement for real } else - fLink.StartMessage(SERVER_FALSE); - + fLink.StartMessage(B_BAD_VALUE); + fLink.Flush(); break; } - + default: printf("ServerApp %s received unhandled message code %ld\n", Signature(), code);