From 0eed9183061a7763972bc2589f9c43489cd078ab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Thu, 20 Aug 2009 17:52:32 +0000 Subject: [PATCH] * Rewrote screen configuration management: VirtualScreen doesn't have anything to do with the configurations now, instead, there is a separated ScreenConfigurations class that maintains all known screen_configurations per workspace (and the Workspace::Private class has two of them, one for the current modes, one for the stored modes). * Added Desktop::{Get|Set}ScreenMode() methods, ServerApp now only calls those. * Getting and setting of anything else than the current screen is now supported. * This change also fixes that a temporarily set screen mode was not being restored on workspace switch. * Also, the Deskbar now seems to have the wrong location a lot, which is something that should be easily fixable therefore. I will look into this next. * Got rid of the unhandy screen_id structure server side, and in BPrivateScreen; we now just use an int32 - the next API break should definitely replace the screen_id with a simple typedef. * Some cleanup. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@32541 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/kits/interface/Bitmap.cpp | 5 +- src/kits/interface/PrivateScreen.cpp | 98 ++++----- src/kits/interface/PrivateScreen.h | 119 ++++++----- src/kits/interface/Screen.cpp | 142 ++++++++----- src/servers/app/BitmapManager.cpp | 15 +- src/servers/app/BitmapManager.h | 38 ++-- src/servers/app/Desktop.cpp | 169 ++++++++++----- src/servers/app/Desktop.h | 40 ++-- src/servers/app/Jamfile | 1 + src/servers/app/MultiLocker.h | 233 ++++++++++---------- src/servers/app/Screen.cpp | 56 ++--- src/servers/app/Screen.h | 20 +- src/servers/app/ScreenConfigurations.cpp | 257 +++++++++++++++++++++++ src/servers/app/ScreenConfigurations.h | 53 +++++ src/servers/app/ScreenManager.cpp | 15 +- src/servers/app/ServerApp.cpp | 150 ++++++------- src/servers/app/ServerWindow.cpp | 124 ++++++----- src/servers/app/VirtualScreen.cpp | 183 ++++------------ src/servers/app/VirtualScreen.h | 82 ++++---- src/servers/app/Workspace.cpp | 17 +- src/servers/app/Workspace.h | 37 ++-- src/servers/app/WorkspacePrivate.h | 55 +++-- 22 files changed, 1126 insertions(+), 783 deletions(-) create mode 100644 src/servers/app/ScreenConfigurations.cpp create mode 100644 src/servers/app/ScreenConfigurations.h diff --git a/src/kits/interface/Bitmap.cpp b/src/kits/interface/Bitmap.cpp index d3c7f1f0b1..6f3b71d0ed 100644 --- a/src/kits/interface/Bitmap.cpp +++ b/src/kits/interface/Bitmap.cpp @@ -9,11 +9,12 @@ * Axel Dörfler, axeld@pinc-software.de */ -/*! - BBitmap objects represent off-screen windows that + +/*! BBitmap objects represent off-screen windows that contain bitmap data. */ + #include #include diff --git a/src/kits/interface/PrivateScreen.cpp b/src/kits/interface/PrivateScreen.cpp index 82df8c853d..d3e80df7c7 100644 --- a/src/kits/interface/PrivateScreen.cpp +++ b/src/kits/interface/PrivateScreen.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2002-2006, Haiku Inc. + * Copyright 2002-2009, Haiku Inc. * Distributed under the terms of the MIT License. * * Authors: @@ -7,8 +7,8 @@ * Axel Dörfler, axeld@pinc-software.de */ -/*! - BPrivateScreen is the class which does the real work for + +/*! BPrivateScreen is the class which does the real work for the proxy class BScreen (it interacts with the app_server). */ @@ -37,10 +37,10 @@ static BObjectList sScreens(2, true); static BLocker sScreenLock("screen lock"); -BPrivateScreen * -BPrivateScreen::Get(BWindow *window) +BPrivateScreen* +BPrivateScreen::Get(BWindow* window) { - screen_id id = B_MAIN_SCREEN_ID; + int32 id = B_MAIN_SCREEN_ID.id; if (window != NULL) { BPrivate::AppServerLink link; @@ -49,22 +49,22 @@ BPrivateScreen::Get(BWindow *window) status_t status; if (link.FlushWithReply(status) == B_OK && status == B_OK) - link.Read(&id); + link.Read(&id); } return _Get(id, false); } -BPrivateScreen * -BPrivateScreen::Get(screen_id id) +BPrivateScreen* +BPrivateScreen::Get(int32 id) { return _Get(id, true); } -BPrivateScreen * -BPrivateScreen::_Get(screen_id id, bool check) +BPrivateScreen* +BPrivateScreen::_Get(int32 id, bool check) { // Nothing works without an app_server connection if (be_app == NULL) @@ -77,7 +77,7 @@ BPrivateScreen::_Get(screen_id id, bool check) for (int32 i = sScreens.CountItems(); i-- > 0;) { BPrivateScreen* screen = sScreens.ItemAt(i); - if (screen->ID().id == id.id) { + if (screen->ID() == id) { screen->_Acquire(); return screen; } @@ -109,7 +109,7 @@ BPrivateScreen::Put(BPrivateScreen* screen) BAutolock locker(sScreenLock); if (screen->_Release()) { - if (screen->ID().id != B_MAIN_SCREEN_ID.id) { + if (screen->ID() != B_MAIN_SCREEN_ID.id) { // we always keep the main screen object around - it will // never go away, even if you disconnect all monitors. sScreens.RemoveItem(screen); @@ -123,9 +123,9 @@ BPrivateScreen::GetNext(BPrivateScreen* screen) { BAutolock locker(sScreenLock); - screen_id id; + int32 id; status_t status = screen->GetNextID(id); - if (status < B_OK) + if (status != B_OK) return NULL; BPrivateScreen* nextScreen = Get(id); @@ -138,11 +138,11 @@ BPrivateScreen::GetNext(BPrivateScreen* screen) bool -BPrivateScreen::_IsValid(screen_id id) +BPrivateScreen::_IsValid(int32 id) { BPrivate::AppServerLink link; link.StartMessage(AS_VALID_SCREEN_ID); - link.Attach(id); + link.Attach(id); status_t status; if (link.FlushWithReply(status) != B_OK || status < B_OK) @@ -193,15 +193,15 @@ BPrivateScreen::IsValid() const status_t -BPrivateScreen::GetNextID(screen_id& id) +BPrivateScreen::GetNextID(int32& id) { BPrivate::AppServerLink link; link.StartMessage(AS_GET_NEXT_SCREEN_ID); - link.Attach(ID()); + link.Attach(ID()); status_t status; if (link.FlushWithReply(status) == B_OK && status == B_OK) { - link.Read(&id); + link.Read(&id); return B_OK; } @@ -212,7 +212,7 @@ BPrivateScreen::GetNextID(screen_id& id) status_t BPrivateScreen::WaitForRetrace(bigtime_t timeout) { - // Get the retrace semaphore if it's the first time + // Get the retrace semaphore if it's the first time // we are called. Cache the value then. if (!fRetraceSemValid) fRetraceSem = _RetraceSemaphore(); @@ -230,7 +230,7 @@ BPrivateScreen::WaitForRetrace(bigtime_t timeout) return status; } - + uint8 BPrivateScreen::IndexForColor(uint8 red, uint8 green, uint8 blue, uint8 alpha) { @@ -267,9 +267,9 @@ BPrivateScreen::InvertIndex(uint8 index) return 0; } - -const color_map * + +const color_map* BPrivateScreen::ColorMap() { if (fColorMap == NULL) { @@ -285,11 +285,11 @@ BPrivateScreen::ColorMap() // which is contained in a shared area created by the server. BPrivate::AppServerLink link; link.StartMessage(AS_SCREEN_GET_COLORMAP); - link.Attach(ID()); + link.Attach(ID()); status_t status; if (link.FlushWithReply(status) == B_OK && status == B_OK) { - fColorMap = (color_map *)malloc(sizeof(color_map)); + fColorMap = (color_map*)malloc(sizeof(color_map)); fOwnsColorMap = true; link.Read(fColorMap); } @@ -300,7 +300,7 @@ BPrivateScreen::ColorMap() status_t -BPrivateScreen::GetBitmap(BBitmap **_bitmap, bool drawCursor, BRect *bounds) +BPrivateScreen::GetBitmap(BBitmap**_bitmap, bool drawCursor, BRect* bounds) { if (_bitmap == NULL) return B_BAD_VALUE; @@ -329,7 +329,7 @@ BPrivateScreen::GetBitmap(BBitmap **_bitmap, bool drawCursor, BRect *bounds) status_t -BPrivateScreen::ReadBitmap(BBitmap *bitmap, bool drawCursor, BRect *bounds) +BPrivateScreen::ReadBitmap(BBitmap* bitmap, bool drawCursor, BRect* bounds) { if (bitmap == NULL) return B_BAD_VALUE; @@ -353,7 +353,7 @@ BPrivateScreen::ReadBitmap(BBitmap *bitmap, bool drawCursor, BRect *bounds) return B_OK; } - + rgb_color BPrivateScreen::DesktopColor(uint32 workspace) { @@ -387,18 +387,18 @@ BPrivateScreen::SetDesktopColor(rgb_color color, uint32 workspace, status_t -BPrivateScreen::ProposeMode(display_mode *target, - const display_mode *low, const display_mode *high) +BPrivateScreen::ProposeMode(display_mode* target, + 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) + // 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(ID()); link.Attach(*target); link.Attach(*low); link.Attach(*high); @@ -415,17 +415,17 @@ BPrivateScreen::ProposeMode(display_mode *target, return status; } - + status_t -BPrivateScreen::GetModeList(display_mode **_modeList, uint32 *_count) +BPrivateScreen::GetModeList(display_mode** _modeList, uint32* _count) { if (_modeList == NULL || _count == NULL) return B_BAD_VALUE; BPrivate::AppServerLink link; link.StartMessage(AS_GET_MODE_LIST); - link.Attach(ID()); + link.Attach(ID()); status_t status = B_ERROR; if (link.FlushWithReply(status) == B_OK && status == B_OK) { @@ -460,7 +460,7 @@ BPrivateScreen::GetMode(uint32 workspace, display_mode *mode) BPrivate::AppServerLink link; link.StartMessage(AS_SCREEN_GET_MODE); - link.Attach(ID()); + link.Attach(ID()); link.Attach(workspace); status_t status = B_ERROR; @@ -481,7 +481,7 @@ BPrivateScreen::SetMode(uint32 workspace, display_mode *mode, bool makeDefault) BPrivate::AppServerLink link; link.StartMessage(AS_SCREEN_SET_MODE); - link.Attach(ID()); + link.Attach(ID()); link.Attach(workspace); link.Attach(*mode); link.Attach(makeDefault); @@ -501,7 +501,7 @@ BPrivateScreen::GetDeviceInfo(accelerant_device_info *info) BPrivate::AppServerLink link; link.StartMessage(AS_GET_ACCELERANT_INFO); - link.Attach(ID()); + link.Attach(ID()); status_t status = B_ERROR; if (link.FlushWithReply(status) == B_OK && status == B_OK) { @@ -521,7 +521,7 @@ BPrivateScreen::GetMonitorInfo(monitor_info* info) BPrivate::AppServerLink link; link.StartMessage(AS_GET_MONITOR_INFO); - link.Attach(ID()); + link.Attach(ID()); status_t status = B_ERROR; if (link.FlushWithReply(status) == B_OK && status == B_OK) { @@ -541,7 +541,7 @@ BPrivateScreen::GetPixelClockLimits(display_mode *mode, uint32 *low, uint32 *hig BPrivate::AppServerLink link; link.StartMessage(AS_GET_PIXEL_CLOCK_LIMITS); - link.Attach(ID()); + link.Attach(ID()); link.Attach(*mode); status_t status; @@ -563,7 +563,7 @@ BPrivateScreen::GetTimingConstraints(display_timing_constraints *constraints) BPrivate::AppServerLink link; link.StartMessage(AS_GET_TIMING_CONSTRAINTS); - link.Attach(ID()); + link.Attach(ID()); status_t status = B_ERROR; if (link.FlushWithReply(status) == B_OK && status == B_OK) { @@ -580,7 +580,7 @@ BPrivateScreen::SetDPMS(uint32 dpmsState) { BPrivate::AppServerLink link; link.StartMessage(AS_SET_DPMS); - link.Attach(ID()); + link.Attach(ID()); link.Attach(dpmsState); status_t status = B_ERROR; @@ -597,7 +597,7 @@ BPrivateScreen::DPMSState() BPrivate::AppServerLink link; link.StartMessage(AS_GET_DPMS_STATE); - link.Attach(ID()); + link.Attach(ID()); status_t status; if (link.FlushWithReply(status) == B_OK && status == B_OK) @@ -614,7 +614,7 @@ BPrivateScreen::DPMSCapabilites() BPrivate::AppServerLink link; link.StartMessage(AS_GET_DPMS_CAPABILITIES); - link.Attach(ID()); + link.Attach(ID()); status_t status; if (link.FlushWithReply(status) == B_OK && status == B_OK) @@ -645,7 +645,7 @@ BPrivateScreen::BytesPerRow() return config.bytes_per_row; } - + // #pragma mark - private methods @@ -654,7 +654,7 @@ BPrivateScreen::_RetraceSemaphore() { BPrivate::AppServerLink link; link.StartMessage(AS_GET_RETRACE_SEMAPHORE); - link.Attach(ID()); + link.Attach(ID()); sem_id id = B_BAD_SEM_ID; status_t status = B_ERROR; @@ -672,7 +672,7 @@ BPrivateScreen::_GetFrameBufferConfig(frame_buffer_config& config) { BPrivate::AppServerLink link; link.StartMessage(AS_GET_FRAME_BUFFER_CONFIG); - link.Attach(ID()); + link.Attach(ID()); status_t status = B_ERROR; if (link.FlushWithReply(status) == B_OK && status == B_OK) { @@ -684,7 +684,7 @@ BPrivateScreen::_GetFrameBufferConfig(frame_buffer_config& config) } -BPrivateScreen::BPrivateScreen(screen_id id) +BPrivateScreen::BPrivateScreen(int32 id) : fID(id), fColorMap(NULL), diff --git a/src/kits/interface/PrivateScreen.h b/src/kits/interface/PrivateScreen.h index 797518833a..1c4a27f512 100644 --- a/src/kits/interface/PrivateScreen.h +++ b/src/kits/interface/PrivateScreen.h @@ -1,5 +1,5 @@ /* - * Copyright 2002-2007, Haiku Inc. + * Copyright 2002-2009, Haiku Inc. * Distributed under the terms of the MIT License. * * Authors: @@ -15,6 +15,7 @@ #include #include + struct color_map; class BBitmap; class BApplication; @@ -24,78 +25,88 @@ class BWindow; namespace BPrivate { class BPrivateScreen { +public: // Constructor and destructor are private. Use the static methods - // CheckOut() and Return() instead. - public: - static BPrivateScreen* Get(BWindow *window); - static BPrivateScreen* Get(screen_id id); - static void Put(BPrivateScreen *screen); + // Get() and Put() instead. - static BPrivateScreen* GetNext(BPrivateScreen* screen); + static BPrivateScreen* Get(BWindow* window); + static BPrivateScreen* Get(int32 id); + static void Put(BPrivateScreen* screen); - bool IsValid() const; - color_space ColorSpace(); - BRect Frame(); - screen_id ID() const { return fID; } - status_t GetNextID(screen_id& id); + static BPrivateScreen* GetNext(BPrivateScreen* screen); - status_t WaitForRetrace(bigtime_t timeout); + bool IsValid() const; + color_space ColorSpace(); + BRect Frame(); + int32 ID() const { return fID; } + status_t GetNextID(int32& id); - uint8 IndexForColor(uint8 red, uint8 green, uint8 blue, uint8 alpha); - rgb_color ColorForIndex(const uint8 index); - uint8 InvertIndex(uint8 index); + status_t WaitForRetrace(bigtime_t timeout); - const color_map *ColorMap(); + uint8 IndexForColor(uint8 red, uint8 green, + uint8 blue, uint8 alpha); + rgb_color ColorForIndex(const uint8 index); + uint8 InvertIndex(uint8 index); - status_t GetBitmap(BBitmap **bitmap, bool drawCursor, BRect *bounds); - status_t ReadBitmap(BBitmap *bitmap, bool drawCursor, BRect *bounds); + const color_map* ColorMap(); - rgb_color DesktopColor(uint32 index); - void SetDesktopColor(rgb_color, uint32, bool); + status_t GetBitmap(BBitmap** bitmap, bool drawCursor, + BRect* bounds); + status_t ReadBitmap(BBitmap* bitmap, bool drawCursor, + BRect* bounds); - status_t ProposeMode(display_mode *target, const display_mode *low, - const display_mode *high); + rgb_color DesktopColor(uint32 index); + void SetDesktopColor(rgb_color, uint32, bool); - 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 ProposeMode(display_mode* target, + const display_mode* low, + const display_mode* high); - status_t GetDeviceInfo(accelerant_device_info *info); - status_t GetMonitorInfo(monitor_info* info); - status_t GetPixelClockLimits(display_mode *mode, uint32 *low, uint32 *high); - status_t GetTimingConstraints(display_timing_constraints *constraints); + 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 SetDPMS(uint32 dpmsState); - uint32 DPMSState(); - uint32 DPMSCapabilites(); + status_t GetDeviceInfo(accelerant_device_info* info); + status_t GetMonitorInfo(monitor_info* info); + status_t GetPixelClockLimits(display_mode* mode, + uint32* _low, uint32* _high); + status_t GetTimingConstraints( + display_timing_constraints* constraints); - void* BaseAddress(); - uint32 BytesPerRow(); + status_t SetDPMS(uint32 dpmsState); + uint32 DPMSState(); + uint32 DPMSCapabilites(); - private: - friend class BObjectList; + void* BaseAddress(); + uint32 BytesPerRow(); - BPrivateScreen(screen_id id); - ~BPrivateScreen(); +private: + friend class BObjectList; - void _Acquire() { fRefCount++; } - bool _Release() { return --fRefCount == 0; } + BPrivateScreen(int32 id); + ~BPrivateScreen(); - sem_id _RetraceSemaphore(); - status_t _GetFrameBufferConfig(frame_buffer_config& config); + void _Acquire() { fRefCount++; } + bool _Release() { return --fRefCount == 0; } - static BPrivateScreen* _Get(screen_id id, bool check); - static bool _IsValid(screen_id id); + sem_id _RetraceSemaphore(); + status_t _GetFrameBufferConfig( + frame_buffer_config& config); - private: - screen_id fID; - int32 fRefCount; - color_map* fColorMap; - sem_id fRetraceSem; - bool fRetraceSemValid; - bool fOwnsColorMap; - BRect fFrame; - bigtime_t fLastUpdate; + static BPrivateScreen* _Get(int32 id, bool check); + static bool _IsValid(int32 id); + +private: + int32 fID; + int32 fRefCount; + color_map* fColorMap; + sem_id fRetraceSem; + bool fRetraceSemValid; + bool fOwnsColorMap; + BRect fFrame; + bigtime_t fLastUpdate; }; } // namespace BPrivate diff --git a/src/kits/interface/Screen.cpp b/src/kits/interface/Screen.cpp index 86f6ff480a..688a73a16b 100644 --- a/src/kits/interface/Screen.cpp +++ b/src/kits/interface/Screen.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2003-2007, Haiku Inc. + * Copyright 2003-2009, Haiku Inc. * Distributed under the terms of the MIT License. * * Authors: @@ -20,7 +20,8 @@ using namespace BPrivate; static const uint32 kCurrentWorkspaceIndex = ~0; -/*! \brief Creates a BScreen object which represents the display with the given screen_id +/*! \brief Creates a BScreen object which represents the display with the given + screen_id \param id The screen_id of the screen to get. In the current implementation, there is only one display (B_MAIN_SCREEN_ID). @@ -28,7 +29,7 @@ static const uint32 kCurrentWorkspaceIndex = ~0; */ BScreen::BScreen(screen_id id) { - fScreen = BPrivateScreen::Get(id); + fScreen = BPrivateScreen::Get(id.id); } @@ -36,21 +37,22 @@ BScreen::BScreen(screen_id id) the given BWindow. \param window A BWindow. */ -BScreen::BScreen(BWindow *window) +BScreen::BScreen(BWindow* window) { fScreen = BPrivateScreen::Get(window); } /*! \brief Releases the resources allocated by the constructor. -*/ +*/ BScreen::~BScreen() { BPrivateScreen::Put(fScreen); } -/*! \brief Checks if the BScreen object represents a real screen connected to the computer. +/*! \brief Checks if the BScreen object represents a real screen connected to + the computer. \return \c true if the BScreen object is valid, \c false if not. */ bool @@ -90,7 +92,8 @@ BScreen::ColorSpace() } -/*! \brief Returns the rectangle that locates the screen in the screen coordinate system. +/*! \brief Returns the rectangle that locates the screen in the screen + coordinate system. \return a BRect that locates the screen in the screen coordinate system. */ BRect @@ -98,21 +101,24 @@ BScreen::Frame() { if (fScreen != NULL) return fScreen->Frame(); - return BRect(0, 0, 0, 0); + return BRect(0, 0, 0, 0); } /*! \brief Returns the identifier for the screen. \return A screen_id struct that identifies the screen. - In the current implementation, this function always returns \c B_MAIN_SCREEN_ID, - even if the object is invalid. + In the current implementation, this function always returns + \c B_MAIN_SCREEN_ID, even if the object is invalid. */ screen_id BScreen::ID() { - if (fScreen != NULL) - return fScreen->ID(); + if (fScreen != NULL) { + screen_id id = { fScreen->ID() }; + return id; + } + return B_MAIN_SCREEN_ID; } @@ -129,7 +135,8 @@ BScreen::WaitForRetrace() /*! \brief Blocks until the monitor has finished the current vertical retrace, or until the given timeout has passed. - \param timeout A bigtime_t which indicates the time to wait before returning. + \param timeout A bigtime_t which indicates the time to wait before + returning. \return \c B_OK if the monitor has retraced in the given amount of time, \c B_ERROR otherwise. */ @@ -174,7 +181,8 @@ BScreen::ColorForIndex(const uint8 index) /*! \brief Returns the "inversion" of the given 8-bit color. \param index An 8-bit color index. - \return An 8-bit color index that represents the "inversion" of the given color. + \return An 8-bit color index that represents the "inversion" of the given + color. */ uint8 BScreen::InvertIndex(uint8 index) @@ -198,34 +206,39 @@ BScreen::ColorMap() /*! \brief Copies the screen's contents into the first argument BBitmap. - \param screen_shot A pointer to a BBitmap pointer, where the function will allocate a BBitmap for you. + \param screen_shot A pointer to a BBitmap pointer, where the function will + allocate a BBitmap for you. \param draw_cursor Specifies if you want the cursor to be drawn. - \param bound Let you specify the area you want copied. If it's NULL, the entire screen is copied. + \param bound Let you specify the area you want copied. If it's NULL, the + entire screen is copied. \return \c B_OK if the operation was succesful, \c B_ERROR on failure. */ status_t -BScreen::GetBitmap(BBitmap **screen_shot, bool draw_cursor, BRect *bound) +BScreen::GetBitmap(BBitmap** _bitmap, bool drawCursor, BRect* bounds) { if (fScreen != NULL) - return fScreen->GetBitmap(screen_shot, draw_cursor, bound); + return fScreen->GetBitmap(_bitmap, drawCursor, bounds); return B_ERROR; } /*! \brief Copies the screen's contents into the first argument BBitmap. - \param screen_shot A pointer to an allocated BBitmap, where the function will store the screen's content. + \param screen_shot A pointer to an allocated BBitmap, where the function + will store the screen's content. \param draw_cursor Specifies if you want the cursor to be drawn. - \param bound Let you specify the area you want copied. If it's NULL, the entire screen is copied. + \param bound Let you specify the area you want copied. If it's NULL, the + entire screen is copied. \return \c B_OK if the operation was succesful, \c B_ERROR on failure. - The only difference between this method and GetBitmap() is that ReadBitmap requires you - to allocate a BBitmap, while the latter will allocate a BBitmap for you. + The only difference between this method and GetBitmap() is that ReadBitmap + requires you to allocate a BBitmap, while the latter will allocate a BBitmap + for you. */ status_t -BScreen::ReadBitmap(BBitmap *buffer, bool draw_cursor, BRect *bound) +BScreen::ReadBitmap(BBitmap* buffer, bool drawCursor, BRect* bounds) { if (fScreen != NULL) - return fScreen->ReadBitmap(buffer, draw_cursor, bound); + return fScreen->ReadBitmap(buffer, drawCursor, bounds); return B_ERROR; } @@ -245,7 +258,8 @@ BScreen::DesktopColor() /*! \brief Returns the color of the desktop in the given workspace. \param workspace The workspace of which you want to have the color. - \return An rgb_color structure which is the color of the desktop in the given workspace. + \return An rgb_color structure which is the color of the desktop in the + given workspace. */ rgb_color BScreen::DesktopColor(uint32 workspace) @@ -259,7 +273,8 @@ BScreen::DesktopColor(uint32 workspace) /*! \brief Set the color of the desktop. \param rgb The color you want to paint the desktop background. - \param stick If you pass \c true here, the color will be maintained across boots. + \param stick If you pass \c true here, the color will be maintained across + boots. */ void BScreen::SetDesktopColor(rgb_color rgb, bool stick) @@ -272,7 +287,8 @@ BScreen::SetDesktopColor(rgb_color rgb, bool stick) /*! \brief Set the color of the desktop in the given workspace. \param rgb The color you want to paint the desktop background. \param index The workspace you want to change the color. - \param stick If you pass \c true here, the color will be maintained across boots. + \param stick If you pass \c true here, the color will be maintained across + boots. */ void BScreen::SetDesktopColor(rgb_color rgb, uint32 index, bool stick) @@ -287,12 +303,15 @@ BScreen::SetDesktopColor(rgb_color rgb, uint32 index, bool stick) \param low The lower limit you want target to be adjusted. \param high The higher limit you want target to be adjusted. \return - - \c B_OK if target (as returned) is supported and falls into the limits. - - \c B_BAD_VALUE if target (as returned) is supported but doesn't fall into the limits. + - \c B_OK if target (as returned) is supported and falls into the + limits. + - \c B_BAD_VALUE if target (as returned) is supported but doesn't fall + into the limits. - \c B_ERROR if target isn't supported. */ status_t -BScreen::ProposeMode(display_mode *target, const display_mode *low, const display_mode *high) +BScreen::ProposeMode(display_mode* target, const display_mode* low, + const display_mode* high) { if (fScreen != NULL) return fScreen->ProposeMode(target, low, high); @@ -300,30 +319,30 @@ BScreen::ProposeMode(display_mode *target, const display_mode *low, const displa } -/*! \brief allocates and returns a list of the display_modes +/*! \brief allocates and returns a list of the display_modes that the graphics card supports. \param mode_list A pointer to a mode_list pointer, where the function will allocate an array of display_mode structures. - \param count A pointer to an integer, where the function will store the amount of - available display modes. + \param count A pointer to an integer, where the function will store the + amount of available display modes. \return \c B_OK. */ status_t -BScreen::GetModeList(display_mode **mode_list, uint32 *count) +BScreen::GetModeList(display_mode** _modeList, uint32* _count) { if (fScreen != NULL) - return fScreen->GetModeList(mode_list, count); + return fScreen->GetModeList(_modeList, _count); return B_ERROR; } /*! \brief Copies the current display_mode into mode. - \param mode A pointer to a display_mode structure, + \param mode A pointer to a display_mode structure, where the current display_mode will be copied. \return \c B_OK if the operation was succesful. */ status_t -BScreen::GetMode(display_mode *mode) +BScreen::GetMode(display_mode* mode) { if (fScreen != NULL) return fScreen->GetMode(kCurrentWorkspaceIndex, mode); @@ -332,12 +351,12 @@ BScreen::GetMode(display_mode *mode) /*! \brief Copies the current display_mode of the given workspace into mode. - \param mode A pointer to a display_mode structure, + \param mode A pointer to a display_mode structure, where the current display_mode will be copied. \return \c B_OK if the operation was succesful. */ status_t -BScreen::GetMode(uint32 workspace, display_mode *mode) +BScreen::GetMode(uint32 workspace, display_mode* mode) { if (fScreen != NULL) return fScreen->GetMode(workspace, mode); @@ -351,7 +370,7 @@ BScreen::GetMode(uint32 workspace, display_mode *mode) \return \c B_OK. */ status_t -BScreen::SetMode(display_mode *mode, bool makeDefault) +BScreen::SetMode(display_mode* mode, bool makeDefault) { if (fScreen != NULL) return fScreen->SetMode(kCurrentWorkspaceIndex, mode, makeDefault); @@ -366,7 +385,7 @@ BScreen::SetMode(display_mode *mode, bool makeDefault) \return \c B_OK. */ status_t -BScreen::SetMode(uint32 workspace, display_mode *mode, bool makeDefault) +BScreen::SetMode(uint32 workspace, display_mode* mode, bool makeDefault) { if (fScreen != NULL) return fScreen->SetMode(workspace, mode, makeDefault); @@ -375,11 +394,12 @@ BScreen::SetMode(uint32 workspace, display_mode *mode, bool makeDefault) /*! \brief Returns information about the graphics card. - \param info An accelerant_device_info struct where to store the retrieved info. + \param info An accelerant_device_info struct where to store the retrieved + info. \return \c B_OK if the operation went fine, otherwise an error code. */ status_t -BScreen::GetDeviceInfo(accelerant_device_info *info) +BScreen::GetDeviceInfo(accelerant_device_info* info) { if (fScreen != NULL) return fScreen->GetDeviceInfo(info); @@ -396,37 +416,41 @@ BScreen::GetMonitorInfo(monitor_info* info) } -/*! \brief Returns, in low and high, the minimum and maximum pixel clock rates +/*! \brief Returns, in low and high, the minimum and maximum pixel clock rates that are possible for the given mode. \param mode A pointer to a display_mode. - \param low A pointer to an int where the function will store the lowest available pixel clock. - \param high A pointer to an int where the function wills tore the highest available pixel clock. + \param low A pointer to an int where the function will store the lowest + available pixel clock. + \param high A pointer to an int where the function wills tore the highest + available pixel clock. \return \c B_OK if the operation went fine, otherwise an error code. */ status_t -BScreen::GetPixelClockLimits(display_mode *mode, uint32 *low, uint32 *high) +BScreen::GetPixelClockLimits(display_mode* mode, uint32* _low, uint32* _high) { if (fScreen != NULL) - return fScreen->GetPixelClockLimits(mode, low, high); + return fScreen->GetPixelClockLimits(mode, _low, _high); return B_ERROR; } -/*! \brief Fills out the dtc structure with the timing constraints of the current display mode. - \param dtc A pointer to a display_timing_constraints structure where the function will store - the timing constraints of the current mode. +/*! \brief Fills out the dtc structure with the timing constraints of the + current display mode. + \param dtc A pointer to a display_timing_constraints structure where the + function will store the timing constraints of the current mode. \return \c B_OK if the operation went fine, otherwise an error code. */ status_t -BScreen::GetTimingConstraints(display_timing_constraints *dtc) +BScreen::GetTimingConstraints(display_timing_constraints* constraints) { if (fScreen != NULL) - return fScreen->GetTimingConstraints(dtc); + return fScreen->GetTimingConstraints(constraints); return B_ERROR; } -/*! \brief Lets you set the VESA Display Power Management Signaling state for the screen. +/*! \brief Lets you set the VESA Display Power Management Signaling state for + the screen. \param dpms_state The DPMS state you want to be set. valid values are: - \c B_DPMS_ON @@ -436,10 +460,10 @@ BScreen::GetTimingConstraints(display_timing_constraints *dtc) \return \c B_OK if the operation went fine, otherwise an error code. */ status_t -BScreen::SetDPMS(uint32 dpms_state) +BScreen::SetDPMS(uint32 dpmsState) { if (fScreen != NULL) - return fScreen->SetDPMS(dpms_state); + return fScreen->SetDPMS(dpmsState); return B_ERROR; } @@ -470,7 +494,8 @@ BScreen::DPMSCapabilites() /*! \brief Returns the BPrivateScreen used by the BScreen object. - \return A pointer to the BPrivateScreen class internally used by the BScreen object. + \return A pointer to the BPrivateScreen class internally used by the BScreen + object. */ BPrivate::BPrivateScreen* BScreen::private_screen() @@ -482,7 +507,8 @@ BScreen::private_screen() /*! \brief Deprecated, use ProposeMode() instead. */ status_t -BScreen::ProposeDisplayMode(display_mode *target, const display_mode *low, const display_mode *high) +BScreen::ProposeDisplayMode(display_mode* target, const display_mode* low, + const display_mode* high) { return ProposeMode(target, low, high); } diff --git a/src/servers/app/BitmapManager.cpp b/src/servers/app/BitmapManager.cpp index c63af2a74a..98e8aebd1d 100644 --- a/src/servers/app/BitmapManager.cpp +++ b/src/servers/app/BitmapManager.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2001-2007, Haiku. + * Copyright 2001-2009, Haiku. * Distributed under the terms of the MIT License. * * Authors: @@ -7,8 +7,8 @@ * Axel Dörfler, axeld@pinc-software.de */ -/*! - Whenever a ServerBitmap associated with a client-side BBitmap needs to be + +/*! Whenever a ServerBitmap associated with a client-side BBitmap needs to be created or destroyed, the BitmapManager needs to handle it. It takes care of all memory management related to them. */ @@ -79,8 +79,8 @@ BitmapManager::~BitmapManager() } -/*! - \brief Allocates a new ServerBitmap. +/*! \brief Allocates a new ServerBitmap. + \param bounds Size of the bitmap \param space Color space of the bitmap \param flags Bitmap flags as defined in Bitmap.h @@ -91,7 +91,7 @@ BitmapManager::~BitmapManager() ServerBitmap* BitmapManager::CreateBitmap(ClientMemoryAllocator* allocator, HWInterface& hwInterface, BRect bounds, color_space space, uint32 flags, - int32 bytesPerRow, screen_id screen, uint8* _allocationFlags) + int32 bytesPerRow, int32 screen, uint8* _allocationFlags) { BAutolock locker(fLock); @@ -201,8 +201,7 @@ BitmapManager::CreateBitmap(ClientMemoryAllocator* allocator, } -/*! - \brief Deletes a ServerBitmap. +/*! \brief Deletes a ServerBitmap. \param bitmap The bitmap to delete */ void diff --git a/src/servers/app/BitmapManager.h b/src/servers/app/BitmapManager.h index 19c3feade8..7f444c1618 100644 --- a/src/servers/app/BitmapManager.h +++ b/src/servers/app/BitmapManager.h @@ -1,5 +1,5 @@ /* - * Copyright 2001-2007, Haiku. + * Copyright 2001-2009, Haiku. * Distributed under the terms of the MIT License. * * Authors: @@ -15,32 +15,34 @@ #include #include + class ClientMemoryAllocator; class HWInterface; class ServerBitmap; + class BitmapManager { - public: - BitmapManager(); - virtual ~BitmapManager(); +public: + BitmapManager(); + virtual ~BitmapManager(); - ServerBitmap* CreateBitmap(ClientMemoryAllocator* allocator, - HWInterface& hwInterface, BRect bounds, - color_space space, uint32 flags, - int32 bytesPerRow = -1, - screen_id screen = B_MAIN_SCREEN_ID, - uint8* _allocationFlags = NULL); - void DeleteBitmap(ServerBitmap* bitmap); + ServerBitmap* CreateBitmap(ClientMemoryAllocator* allocator, + HWInterface& hwInterface, BRect bounds, + color_space space, uint32 flags, + int32 bytesPerRow = -1, + int32 screen = B_MAIN_SCREEN_ID.id, + uint8* _allocationFlags = NULL); + void DeleteBitmap(ServerBitmap* bitmap); - void SuspendOverlays(); - void ResumeOverlays(); + void SuspendOverlays(); + void ResumeOverlays(); - protected: - BList fBitmapList; - BList fOverlays; - BLocker fLock; +protected: + BList fBitmapList; + BList fOverlays; + BLocker fLock; }; -extern BitmapManager *gBitmapManager; +extern BitmapManager* gBitmapManager; #endif /* BITMAP_MANAGER_H */ diff --git a/src/servers/app/Desktop.cpp b/src/servers/app/Desktop.cpp index ee3a104b61..4bf52158e1 100644 --- a/src/servers/app/Desktop.cpp +++ b/src/servers/app/Desktop.cpp @@ -9,6 +9,7 @@ * Andrej Spielmann, */ + /*! Class used to encapsulate desktop management */ @@ -363,7 +364,8 @@ Desktop::Init() fWorkspaces[i].RestoreConfiguration(*fSettings->WorkspacesMessage(i)); } - fVirtualScreen.RestoreConfiguration(*this, fSettings->WorkspacesMessage(0)); + fVirtualScreen.SetConfiguration(*this, + fWorkspaces[0].CurrentScreenConfiguration()); // TODO: temporary workaround, fActiveScreen will be removed fActiveScreen = fVirtualScreen.ScreenAt(0); @@ -827,18 +829,19 @@ Desktop::RedrawBackground() } -/*! - \brief Store the workspace configuration +/*! \brief Stores the workspace configuration. + You must hold the window lock when calling this method. */ void Desktop::StoreWorkspaceConfiguration(int32 index) { - const BMessage *oldSettings = fSettings->WorkspacesMessage(index); - // store settings + // Retrieve settings + BMessage settings; - if (oldSettings) - settings = *oldSettings; fWorkspaces[index].StoreConfiguration(settings); + + // and store them + fSettings->SetWorkspacesMessage(index, settings); fSettings->Save(kWorkspacesSettings); } @@ -874,8 +877,7 @@ Desktop::SetWorkspacesLayout(int32 newColumns, int32 newRows) } -/*! - Returns the virtual screen frame of the workspace specified by \a index. +/*! Returns the virtual screen frame of the workspace specified by \a index. */ BRect Desktop::WorkspaceFrame(int32 index) const @@ -888,7 +890,8 @@ Desktop::WorkspaceFrame(int32 index) const int32 width; int32 height; fSettings->WorkspacesMessage(index)->FindMessage("screen", &screenData); - if (screenData.FindInt32("width", &width) != B_OK || screenData.FindInt32("height", &height) != B_OK) + if (screenData.FindInt32("width", &width) != B_OK + || screenData.FindInt32("height", &height) != B_OK) frame = fVirtualScreen.Frame(); else frame.Set(0.0, 0.0, width - 1, height - 1); @@ -1000,12 +1003,12 @@ Desktop::_SetWorkspace(int32 index) // Change the display modes, if needed uint32 changedScreens; - fVirtualScreen.RestoreConfiguration(*this, - fSettings->WorkspacesMessage(index), &changedScreens); + fVirtualScreen.SetConfiguration(*this, + fWorkspaces[index].CurrentScreenConfiguration(), &changedScreens); for (int32 i = 0; changedScreens != 0; i++, changedScreens /= 2) { if ((changedScreens & (1 << i)) != 0) - ScreenChanged(fVirtualScreen.ScreenAt(i), false); + ScreenChanged(fVirtualScreen.ScreenAt(i)); } // Show windows, and include them in the changed region - but only @@ -1075,8 +1078,10 @@ Desktop::_SetWorkspace(int32 index) if (window->InWorkspace(previousIndex) || window->IsHidden() || (window == fMouseEventWindow && fMouseEventWindow->IsNormal()) - || (!window->IsNormal() && window->HasInSubset(fMouseEventWindow))) { - // this window was visible before, and is already handled in the above loop + || (!window->IsNormal() + && window->HasInSubset(fMouseEventWindow))) { + // This window was visible before, and is already handled in the + // above loop continue; } @@ -1095,7 +1100,8 @@ Desktop::_SetWorkspace(int32 index) // Set new focus to the front window, but keep focus to a floating // window if still visible - if (!_Windows(index).HasWindow(FocusWindow()) || !FocusWindow()->IsFloating()) + if (!_Windows(index).HasWindow(FocusWindow()) + || !FocusWindow()->IsFloating()) SetFocusWindow(FrontWindow()); _WindowChanged(NULL); @@ -1115,15 +1121,108 @@ Desktop::_SetWorkspace(int32 index) } -void -Desktop::ScreenChanged(Screen* screen, bool makeDefault) +status_t +Desktop::SetScreenMode(int32 workspace, int32 id, const display_mode& mode, + bool makeDefault) { - // TODO: confirm that everywhere this is used, - // the Window WriteLock is held + // ~0 is used as the current workspace in PrivateScreen + if (workspace == ~0) + workspace = fCurrentWorkspace; + + if (workspace < 0 || workspace > kMaxWorkspaces) + return B_BAD_VALUE; + + AutoWriteLocker _(fWindowLock); + + Screen* screen = fVirtualScreen.ScreenByID(id); + if (screen == NULL) + return B_NAME_NOT_FOUND; + + // Check if the mode has actually changed + + if (workspace == fCurrentWorkspace) { + // retrieve from current screen + display_mode oldMode; + screen->GetMode(oldMode); + + if (!memcmp(&oldMode, &mode, sizeof(display_mode))) + return B_OK; + } else { + // retrieve from settings + screen_configuration* configuration + = fWorkspaces[workspace].CurrentScreenConfiguration().CurrentByID( + screen->ID()); + if (configuration != NULL + && !memcmp(&configuration->mode, &mode, sizeof(display_mode))) + return B_OK; + } + + // Set the new one + + status_t status = screen->SetMode(mode); + if (status != B_OK) + return status; + + // Update our configurations + + monitor_info info; + bool hasInfo = screen->GetMonitorInfo(info) == B_OK; + + fWorkspaces[workspace].CurrentScreenConfiguration().Set(id, + hasInfo ? &info : NULL, screen->Frame(), mode); + if (makeDefault) { + fWorkspaces[workspace].StoredScreenConfiguration().Set(id, + hasInfo ? &info : NULL, screen->Frame(), mode); + StoreWorkspaceConfiguration(workspace); + } + + ScreenChanged(screen); + return B_OK; +} + + +status_t +Desktop::GetScreenMode(int32 workspace, int32 id, display_mode& mode) +{ + // ~0 is used as the current workspace in PrivateScreen + if (workspace == ~0) + workspace = fCurrentWorkspace; + + if (workspace < 0 || workspace > kMaxWorkspaces) + return B_BAD_VALUE; + + AutoReadLocker _(fWindowLock); + + if (workspace == fCurrentWorkspace) { + // retrieve from current screen + Screen* screen = fVirtualScreen.ScreenByID(id); + if (screen == NULL) + return B_NAME_NOT_FOUND; + + screen->GetMode(mode); + return B_OK; + } + + // retrieve from settings + screen_configuration* configuration + = fWorkspaces[workspace].CurrentScreenConfiguration().CurrentByID(id); + if (configuration == NULL) + return B_NAME_NOT_FOUND; + + mode = configuration->mode; + return B_OK; +} + + +void +Desktop::ScreenChanged(Screen* screen) +{ + ASSERT(fWindowLock.IsWriteLocked()); // the entire screen is dirty, because we're actually // operating on an all new buffer in memory BRegion dirty(screen->Frame()); + // update our cached screen region fScreenRegion.Set(screen->Frame()); gInputManager->UpdateScreenBounds(screen->Frame()); @@ -1145,42 +1244,16 @@ Desktop::ScreenChanged(Screen* screen, bool makeDefault) update.AddRect("frame", screen->Frame()); update.AddInt32("mode", screen->ColorSpace()); + fVirtualScreen.UpdateFrame(); + // TODO: currently ignores the screen argument! for (Window* window = fAllWindows.FirstWindow(); window != NULL; window = window->NextWindow(kAllWindowList)) { window->ServerWindow()->ScreenChanged(&update); - window->ServerWindow()->SendMessageToClient(&update); - } - - fVirtualScreen.UpdateFrame(); - - if (makeDefault) { - StoreConfiguration(fCurrentWorkspace); } } -status_t -Desktop::StoreConfiguration(int32 workspace) -{ - // TODO: This only works because StoreConfiguration is never called - // for an inactive workspace. fVirtualScreen has the screen mode - // of the current workspace. - - if (workspace >= 0 && workspace < fSettings->WorkspacesCount()) { - // store settings - BMessage settings; - fVirtualScreen.StoreConfiguration(settings); - fWorkspaces[workspace].StoreConfiguration(settings); - - fSettings->SetWorkspacesMessage(workspace, settings); - fSettings->Save(kWorkspacesSettings); - return B_OK; - } - - return B_BAD_VALUE; -} - // #pragma mark - Methods for Window manipulation diff --git a/src/servers/app/Desktop.h b/src/servers/app/Desktop.h index e1856adb44..e27b8e863e 100644 --- a/src/servers/app/Desktop.h +++ b/src/servers/app/Desktop.h @@ -33,6 +33,7 @@ #include #include + #define USE_MULTI_LOCKER 1 #if USE_MULTI_LOCKER @@ -41,6 +42,7 @@ # include #endif + class BMessage; class DrawingEngine; @@ -54,6 +56,7 @@ namespace BPrivate { class LinkSender; }; + class Desktop : public MessageLooper, public ScreenOwner { public: Desktop(uid_t userID); @@ -71,14 +74,7 @@ class Desktop : public MessageLooper, public ScreenOwner { void BroadcastToAllApps(int32 code); void BroadcastToAllWindows(int32 code); - // Screen and drawing related methods - - Screen* ScreenAt(int32 index) const - { return fActiveScreen; } - Screen* ActiveScreen() const - { return fActiveScreen; } - - CursorManager& GetCursorManager() { return fCursorManager; } + // Mouse and cursor methods void SetCursor(ServerCursor* cursor); ServerCursorReference Cursor() const; @@ -91,11 +87,22 @@ class Desktop : public MessageLooper, public ScreenOwner { void GetLastMouseState(BPoint* position, int32* buttons) const; // for use by ServerWindow - void ScreenChanged(Screen* screen, bool makeDefault); - void ScreenRemoved(Screen* screen) {} - void ScreenAdded(Screen* screen) {} - bool ReleaseScreen(Screen* screen) { return false; } - status_t StoreConfiguration(int32 workspace); + + // Screen and drawing related methods + + Screen* ScreenAt(int32 index) const + { return fActiveScreen; } + Screen* ActiveScreen() const + { return fActiveScreen; } + + CursorManager& GetCursorManager() { return fCursorManager; } + + status_t SetScreenMode(int32 workspace, int32 id, + const display_mode& mode, bool makeDefault); + status_t GetScreenMode(int32 workspace, int32 id, + display_mode& mode); + + void ScreenChanged(Screen* screen); const ::VirtualScreen& VirtualScreen() const { return fVirtualScreen; } DrawingEngine* GetDrawingEngine() const @@ -103,6 +110,11 @@ class Desktop : public MessageLooper, public ScreenOwner { ::HWInterface* HWInterface() const { return fVirtualScreen.HWInterface(); } + // ScreenOwner implementation + void ScreenRemoved(Screen* screen) {} + void ScreenAdded(Screen* screen) {} + bool ReleaseScreen(Screen* screen) { return false; } + // Workspace methods void SetWorkspaceAsync(int32 index); @@ -183,6 +195,8 @@ class Desktop : public MessageLooper, public ScreenOwner { { return fWindowLock.WriteLock(); } void UnlockAllWindows() { fWindowLock.WriteUnlock(); } + + MultiLocker WindowLocker() { return fWindowLock; } #else // USE_MULTI_LOCKER bool LockSingleWindow() { return fWindowLock.Lock(); } diff --git a/src/servers/app/Jamfile b/src/servers/app/Jamfile index 620b38125d..24b680bb88 100644 --- a/src/servers/app/Jamfile +++ b/src/servers/app/Jamfile @@ -44,6 +44,7 @@ Server app_server : RGBColor.cpp RegionPool.cpp Screen.cpp + ScreenConfigurations.cpp ScreenManager.cpp ServerApp.cpp ServerBitmap.cpp diff --git a/src/servers/app/MultiLocker.h b/src/servers/app/MultiLocker.h index 3938063d0d..d3e588f421 100644 --- a/src/servers/app/MultiLocker.h +++ b/src/servers/app/MultiLocker.h @@ -1,164 +1,177 @@ /* - * Copyright 2005-2007, Haiku, Inc. All Rights Reserved. + * Copyright 2005-2009, Haiku, Inc. All Rights Reserved. * Distributed under the terms of the MIT license. * * Copyright 1999, Be Incorporated. All Rights Reserved. * This file may be used under the terms of the Be Sample Code License. */ - -/*! multiple-reader single-writer locking class */ - -// IMPORTANT: -// * nested read locks are not supported -// * a reader becomming the write is not supported -// * nested write locks are supported -// * a writer can do read locks, even nested ones -// * in case of problems, #define DEBUG 1 in the .cpp - #ifndef MULTI_LOCKER_H #define MULTI_LOCKER_H +/*! multiple-reader single-writer locking class + + IMPORTANT: + * nested read locks are not supported + * a reader becoming the write is not supported + * nested write locks are supported + * a writer can do read locks, even nested ones + * in case of problems, #define DEBUG 1 in the .cpp +*/ + + #include #define MULTI_LOCKER_TIMING 0 #if DEBUG # define MULTI_LOCKER_DEBUG DEBUG +#endif + +#if MULTI_LOCKER_DEBUG +# define ASSERT_MULTI_LOCKED(x) ((x).IsWriteLocked() || (x).IsReadLocked()) +# define ASSERT_MULTI_READ_LOCKED(x) ((x).IsReadLocked()) +# define ASSERT_MULTI_WRITE_LOCKED(x) ((x).IsWriteLocked()) #else # define MULTI_LOCKER_DEBUG 0 +# define ASSERT_MULTI_LOCKED(x) ; +# define ASSERT_MULTI_READ_LOCKED(x) ; +# define ASSERT_MULTI_WRITE_LOCKED(x) ; #endif + class MultiLocker { - public: - MultiLocker(const char* baseName); - virtual ~MultiLocker(); +public: + MultiLocker(const char* baseName); + virtual ~MultiLocker(); - status_t InitCheck(); - - // locking for reading or writing - bool ReadLock(); - bool WriteLock(); + status_t InitCheck(); - // unlocking after reading or writing - bool ReadUnlock(); - bool WriteUnlock(); + // locking for reading or writing + bool ReadLock(); + bool WriteLock(); - // does the current thread hold a write lock ? - bool IsWriteLocked(uint32 *stackBase = NULL, - thread_id *thread = NULL); + // unlocking after reading or writing + bool ReadUnlock(); + bool WriteUnlock(); + + // does the current thread hold a write lock ? + bool IsWriteLocked(uint32 *stackBase = NULL, + thread_id *thread = NULL); #if MULTI_LOCKER_DEBUG - // in DEBUG mode returns whether the lock is held - // in non-debug mode returns true - bool IsReadLocked(); + // in DEBUG mode returns whether the lock is held + // in non-debug mode returns true + bool IsReadLocked(); #endif - private: +private: #if MULTI_LOCKER_DEBUG - // functions for managing the DEBUG reader array - void _RegisterThread(); - void _UnregisterThread(); + // functions for managing the DEBUG reader array + void _RegisterThread(); + void _UnregisterThread(); - sem_id fLock; - int32* fDebugArray; - int32 fMaxThreads; + sem_id fLock; + int32* fDebugArray; + int32 fMaxThreads; #else - // readers adjust count and block on fReadSem when a writer - // hold the lock - int32 fReadCount; - sem_id fReadSem; - // writers adjust the count and block on fWriteSem - // when readers hold the lock - int32 fWriteCount; - sem_id fWriteSem; - // writers must acquire fWriterLock when acquiring a write lock - int32 fLockCount; - sem_id fWriterLock; + // readers adjust count and block on fReadSem when a writer + // hold the lock + int32 fReadCount; + sem_id fReadSem; + // writers adjust the count and block on fWriteSem + // when readers hold the lock + int32 fWriteCount; + sem_id fWriteSem; + // writers must acquire fWriterLock when acquiring a write lock + int32 fLockCount; + sem_id fWriterLock; #endif // MULTI_LOCKER_DEBUG - status_t fInit; - int32 fWriterNest; - thread_id fWriterThread; - uint32 fWriterStackBase; + status_t fInit; + int32 fWriterNest; + thread_id fWriterThread; + uint32 fWriterStackBase; #if MULTI_LOCKER_TIMING - uint32 rl_count; - bigtime_t rl_time; - uint32 ru_count; - bigtime_t ru_time; - uint32 wl_count; - bigtime_t wl_time; - uint32 wu_count; - bigtime_t wu_time; - uint32 islock_count; - bigtime_t islock_time; + uint32 rl_count; + bigtime_t rl_time; + uint32 ru_count; + bigtime_t ru_time; + uint32 wl_count; + bigtime_t wl_time; + uint32 wu_count; + bigtime_t wu_time; + uint32 islock_count; + bigtime_t islock_time; #endif }; + class AutoWriteLocker { - public: - AutoWriteLocker(MultiLocker* lock) - : - fLock(*lock) - { - fLock.WriteLock(); - } +public: + AutoWriteLocker(MultiLocker* lock) + : + fLock(*lock) + { + fLock.WriteLock(); + } - AutoWriteLocker(MultiLocker& lock) - : - fLock(lock) - { - fLock.WriteLock(); - } + AutoWriteLocker(MultiLocker& lock) + : + fLock(lock) + { + fLock.WriteLock(); + } - bool IsLocked() const - { - return fLock.IsWriteLocked(); - } + bool IsLocked() const + { + return fLock.IsWriteLocked(); + } - ~AutoWriteLocker() - { - fLock.WriteUnlock(); - } + ~AutoWriteLocker() + { + fLock.WriteUnlock(); + } - private: - MultiLocker& fLock; +private: + MultiLocker& fLock; }; + class AutoReadLocker { - public: - AutoReadLocker(MultiLocker* lock) - : - fLock(*lock) - { - fLocked = fLock.ReadLock(); - } +public: + AutoReadLocker(MultiLocker* lock) + : + fLock(*lock) + { + fLocked = fLock.ReadLock(); + } - AutoReadLocker(MultiLocker& lock) - : - fLock(lock) - { - fLocked = fLock.ReadLock(); - } + AutoReadLocker(MultiLocker& lock) + : + fLock(lock) + { + fLocked = fLock.ReadLock(); + } - ~AutoReadLocker() - { - Unlock(); - } + ~AutoReadLocker() + { + Unlock(); + } - void - Unlock() - { - if (fLocked) { - fLock.ReadUnlock(); - fLocked = false; - } + void + Unlock() + { + if (fLocked) { + fLock.ReadUnlock(); + fLocked = false; } + } - private: - MultiLocker& fLock; - bool fLocked; +private: + MultiLocker& fLock; + bool fLocked; }; #endif // MULTI_LOCKER_H diff --git a/src/servers/app/Screen.cpp b/src/servers/app/Screen.cpp index 8156759624..f1ab5b54de 100644 --- a/src/servers/app/Screen.cpp +++ b/src/servers/app/Screen.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001-2008, Haiku, Inc. + * Copyright 2001-2009, Haiku, Inc. * Distributed under the terms of the MIT license. * * Authors: @@ -40,19 +40,19 @@ get_mode_frequency(const display_mode& mode) Screen::Screen(::HWInterface *interface, int32 id) - : fID(id), - fDriver(interface ? new DrawingEngine(interface) : NULL), - fHWInterface(interface), - fIsDefault(true) + : + fID(id), + fDriver(interface ? new DrawingEngine(interface) : NULL), + fHWInterface(interface) { } Screen::Screen() - : fID(-1), - fDriver(NULL), - fHWInterface(NULL), - fIsDefault(true) + : + fID(-1), + fDriver(NULL), + fHWInterface(NULL) { } @@ -64,10 +64,10 @@ Screen::~Screen() delete fHWInterface; } + /*! Finds the mode in the mode list that is closest to the mode specified. As long as the mode list is not empty, this method will always succeed. */ - status_t Screen::Initialize() { @@ -89,13 +89,13 @@ Screen::Shutdown() status_t -Screen::SetMode(const display_mode& mode, bool makeDefault) +Screen::SetMode(const display_mode& mode) { display_mode current; - GetMode(¤t); - if (!memcmp(&mode, ¤t, sizeof(display_mode))) + GetMode(current); + if (!memcmp(&mode, ¤t, sizeof(display_mode))) return B_OK; - + gBitmapManager->SuspendOverlays(); status_t status = fHWInterface->SetMode(mode); @@ -103,16 +103,13 @@ Screen::SetMode(const display_mode& mode, bool makeDefault) gBitmapManager->ResumeOverlays(); - if (status >= B_OK) - fIsDefault = makeDefault; - return status; } status_t Screen::SetMode(uint16 width, uint16 height, uint32 colorSpace, - const display_timing& timing, bool makeDefault) + const display_timing& timing) { display_mode mode; mode.timing = timing; @@ -123,7 +120,7 @@ Screen::SetMode(uint16 width, uint16 height, uint32 colorSpace, mode.v_display_start = 0; mode.flags = 0; - return SetMode(mode, makeDefault); + return SetMode(mode); } @@ -167,10 +164,10 @@ Screen::SetBestMode(uint16 width, uint16 height, uint32 colorSpace, * mode.timing.v_total / 10 * int32(frequency * 10)) / 1000; adjusted = true; } - status = SetMode(mode, false); - if (status < B_OK && adjusted) { + status = SetMode(mode); + if (status != B_OK && adjusted) { // try again with the unchanged mode - status = SetMode(originalMode, false); + status = SetMode(originalMode); } return status; @@ -182,17 +179,17 @@ Screen::SetPreferredMode() { display_mode mode; status_t status = fHWInterface->GetPreferredMode(&mode); - if (status < B_OK) + if (status != B_OK) return status; - return SetMode(mode, false); + return SetMode(mode); } void -Screen::GetMode(display_mode* mode) const +Screen::GetMode(display_mode& mode) const { - fHWInterface->GetMode(mode); + fHWInterface->GetMode(&mode); } @@ -217,6 +214,13 @@ Screen::GetMonitorInfo(monitor_info& info) const } +void +Screen::SetFrame(const BRect& rect) +{ + // TODO: multi-monitor support... +} + + BRect Screen::Frame() const { diff --git a/src/servers/app/Screen.h b/src/servers/app/Screen.h index 245af74f58..9dd4e542a8 100644 --- a/src/servers/app/Screen.h +++ b/src/servers/app/Screen.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001-2008, Haiku, Inc. + * Copyright 2001-2009, Haiku, Inc. * Distributed under the terms of the MIT license. * * Authors: @@ -20,7 +20,7 @@ class DrawingEngine; class HWInterface; class Screen { - public: +public: Screen(::HWInterface *interface, int32 id); Screen(); virtual ~Screen(); @@ -31,31 +31,30 @@ class Screen { int32 ID() const { return fID; } status_t GetMonitorInfo(monitor_info& info) const; - status_t SetMode(const display_mode& mode, - bool makeDefault); + status_t SetMode(const display_mode& mode); status_t SetMode(uint16 width, uint16 height, uint32 colorspace, - const display_timing& timing, - bool makeDefault); + const display_timing& timing); status_t SetPreferredMode(); status_t SetBestMode(uint16 width, uint16 height, uint32 colorspace, float frequency, bool strict = true); - void GetMode(display_mode* mode) const; + void GetMode(display_mode& mode) const; void GetMode(uint16 &width, uint16 &height, uint32 &colorspace, float &frequency) const; + + void SetFrame(const BRect& rect); + BRect Frame() const; color_space ColorSpace() const; - bool IsDefaultMode() const { return fIsDefault; } - inline DrawingEngine* GetDrawingEngine() const { return fDriver; } inline ::HWInterface* HWInterface() const { return fHWInterface; } - private: +private: int32 _FindBestMode(const display_mode* modeList, uint32 count, uint16 width, uint16 height, uint32 colorspace, float frequency) const; @@ -63,7 +62,6 @@ class Screen { int32 fID; DrawingEngine* fDriver; ::HWInterface* fHWInterface; - bool fIsDefault; }; #endif /* SCREEN_H */ diff --git a/src/servers/app/ScreenConfigurations.cpp b/src/servers/app/ScreenConfigurations.cpp new file mode 100644 index 0000000000..1b4a107094 --- /dev/null +++ b/src/servers/app/ScreenConfigurations.cpp @@ -0,0 +1,257 @@ +/* + * Copyright 2005-2009, Axel Dörfler, axeld@pinc-software.de. + * This file may be used under the terms of the MIT License. + */ + + +#include "ScreenConfigurations.h" + +#include +#include + +#include + + +ScreenConfigurations::ScreenConfigurations() + : + fConfigurations(10, true) +{ +} + + +ScreenConfigurations::~ScreenConfigurations() +{ +} + + +screen_configuration* +ScreenConfigurations::CurrentByID(int32 id) const +{ + for (int32 i = fConfigurations.CountItems(); i-- > 0;) { + screen_configuration* configuration = fConfigurations.ItemAt(i); + + if (configuration->id == id && configuration->is_current) + return configuration; + } + + return NULL; +} + + +screen_configuration* +ScreenConfigurations::BestFit(int32 id, const monitor_info* info, + bool* _exactMatch) const +{ + if (info == NULL) { + // only look for a matching ID - this is all we have + for (uint32 pass = 0; pass < 2; pass++) { + for (int32 i = fConfigurations.CountItems(); i-- > 0;) { + screen_configuration* configuration = fConfigurations.ItemAt(i); + + if ((pass != 0 || !configuration->has_info) + && id == configuration->id) + return configuration; + } + } + + return NULL; + } + + // look for a configuration that matches the monitor + + bool exactMatch = false; + int32 bestScore = 0; + int32 bestIndex = -1; + BMessage stored; + + for (int32 i = fConfigurations.CountItems(); i-- > 0;) { + screen_configuration* configuration = fConfigurations.ItemAt(i); + int32 score = 0; + + // TODO: should we ignore unnamed settings here completely? + + if (configuration->id == id) + score++; + + if (!strcasecmp(configuration->info.vendor, info->vendor) + && !strcasecmp(configuration->info.name, info->name) + && configuration->info.product_id == info->product_id) { + score += 2; + if (info->serial_number[0] != '\0' + && !strcmp(configuration->info.serial_number, + info->serial_number)) { + exactMatch = true; + score += 2; + } + if (configuration->info.produced.year == info->produced.year + && configuration->info.produced.week == info->produced.week) + score++; + } else + score -= 2; + + if (score > bestScore) { + bestScore = score; + bestIndex = i; + } + } + + if (bestIndex < 0) + return NULL; + + if (_exactMatch != NULL) + *_exactMatch = exactMatch; + + return fConfigurations.ItemAt(bestIndex); +} + + +status_t +ScreenConfigurations::Set(int32 id, const monitor_info* info, + const BRect& frame, const display_mode& mode) +{ + // Find configuration that we can overwrite + + bool exactMatch; + screen_configuration* configuration = BestFit(id, info, &exactMatch); + + if (configuration != NULL && configuration->has_info && !exactMatch) { + // only overwrite exact or unspecified configurations + configuration->is_current = false; + // TODO: provide a more obvious current mechanism... + configuration = NULL; + } + + if (configuration == NULL) { + // we need a new configuration to store + configuration = new (std::nothrow) screen_configuration; + if (configuration == NULL) + return B_NO_MEMORY; + + fConfigurations.AddItem(configuration); + } + + configuration->id = id; + configuration->frame = frame; + configuration->is_current = true; + + if (info != NULL) { + memcpy(&configuration->info, info, sizeof(monitor_info)); + configuration->has_info = true; + } else + configuration->has_info = false; + + memcpy(&configuration->mode, &mode, sizeof(display_mode)); + + return B_OK; +} + + +status_t +ScreenConfigurations::Update(int32 id, const display_mode& mode) +{ + screen_configuration* configuration = CurrentByID(id); + if (configuration == NULL) + return B_BAD_VALUE; + + configuration->is_current = true; + + memcpy(&configuration->mode, &mode, sizeof(display_mode)); + + return B_OK; +} + + +/*! Stores all configurations as separate BMessages into the provided + \a settings container. +*/ +status_t +ScreenConfigurations::Store(BMessage& settings) const +{ + // Store the configuration of all current screens + + for (int32 i = 0; i < fConfigurations.CountItems(); i++) { + screen_configuration* configuration = fConfigurations.ItemAt(i); + + BMessage screenSettings; + screenSettings.AddInt32("id", configuration->id); + + if (configuration->has_info) { + screenSettings.AddString("vendor", configuration->info.vendor); + screenSettings.AddString("name", configuration->info.name); + screenSettings.AddInt32("product id", + configuration->info.product_id); + screenSettings.AddString("serial", + configuration->info.serial_number); + screenSettings.AddInt32("produced week", + configuration->info.produced.week); + screenSettings.AddInt32("produced year", + configuration->info.produced.year); + } + + screenSettings.AddRect("frame", configuration->frame); + screenSettings.AddData("mode", B_RAW_TYPE, &configuration->mode, + sizeof(display_mode)); + + settings.AddMessage("screen", &screenSettings); + } + + return B_OK; +} + + +status_t +ScreenConfigurations::Restore(const BMessage& settings) +{ + fConfigurations.MakeEmpty(); + + BMessage stored; + for (int32 i = 0; settings.FindMessage("screen", i, &stored) == B_OK; i++) { + const display_mode* mode; + ssize_t size; + int32 id; + if (stored.FindInt32("id", &id) != B_OK + || stored.FindData("mode", B_RAW_TYPE, (const void**)&mode, + &size) != B_OK + || size == sizeof(display_mode)) + continue; + + screen_configuration* configuration + = new(std::nothrow) screen_configuration; + if (configuration == NULL) + return B_NO_MEMORY; + + configuration->id = id; + configuration->is_current = false; + + const char* vendor; + const char* name; + uint32 productID; + const char* serial; + int32 week, year; + if (stored.FindString("vendor", &vendor) == B_OK + && stored.FindString("name", &name) == B_OK + && stored.FindInt32("product id", (int32*)&productID) == B_OK + && stored.FindString("serial", &serial) == B_OK + && stored.FindInt32("produced week", &week) == B_OK + && stored.FindInt32("produced year", &year) == B_OK) { + // create monitor info + strlcpy(configuration->info.vendor, vendor, + sizeof(monitor_info::vendor)); + strlcpy(configuration->info.name, name, sizeof(monitor_info::name)); + strlcpy(configuration->info.serial_number, serial, + sizeof(monitor_info::serial_number)); + configuration->info.product_id = productID; + configuration->info.produced.week = week; + configuration->info.produced.year = year; + configuration->has_info = true; + } else + configuration->has_info = false; + + stored.FindRect("frame", &configuration->frame); + memcpy(&configuration->mode, mode, sizeof(display_mode)); + + fConfigurations.AddItem(configuration); + } + + return B_OK; +} diff --git a/src/servers/app/ScreenConfigurations.h b/src/servers/app/ScreenConfigurations.h new file mode 100644 index 0000000000..959f24d8c3 --- /dev/null +++ b/src/servers/app/ScreenConfigurations.h @@ -0,0 +1,53 @@ +/* + * Copyright 2009, Axel Dörfler, axeld@pinc-software.de. + * This file may be used under the terms of the MIT License. + */ +#ifndef SCREEN_CONFIGURATIONS_H +#define SCREEN_CONFIGURATIONS_H + + +#include +#include + +#include + + +class BMessage; + + +struct screen_configuration { + int32 id; + monitor_info info; + BRect frame; + display_mode mode; + bool has_info; + bool is_current; +}; + + +class ScreenConfigurations { +public: + ScreenConfigurations(); + ~ScreenConfigurations(); + + screen_configuration* CurrentByID(int32 id) const; + screen_configuration* BestFit(int32 id, const monitor_info* info, + bool* _exactMatch = NULL) const; + + status_t Set(int32 id, const monitor_info* info, + const BRect& frame, + const display_mode& mode); + status_t Update(int32 id, const display_mode& mode); + + status_t Store(BMessage& settings) const; + status_t Restore(const BMessage& settings); + +private: + typedef BObjectList ConfigurationList; + + ConfigurationList fConfigurations; +}; + + +#endif // SCREEN_CONFIGURATIONS_H + diff --git a/src/servers/app/ScreenManager.cpp b/src/servers/app/ScreenManager.cpp index 0df01b3f4f..c117358562 100644 --- a/src/servers/app/ScreenManager.cpp +++ b/src/servers/app/ScreenManager.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2005-2008, Haiku. + * Copyright 2005-2009, Haiku. * Distributed under the terms of the MIT License. * * Authors: @@ -35,7 +35,8 @@ ScreenManager* gScreenManager; ScreenManager::ScreenManager() - : BLooper("screen manager"), + : + BLooper("screen manager"), fScreenList(4) { _ScanDrivers(); @@ -93,7 +94,7 @@ ScreenManager::AcquireScreens(ScreenOwner* owner, int32* wishList, // ToDo: don't ignore the wish list for (int32 i = 0; i < fScreenList.CountItems(); i++) { - screen_item *item = fScreenList.ItemAt(i); + screen_item* item = fScreenList.ItemAt(i); if (item->owner == NULL && list.AddItem(item->screen)) { item->owner = owner; @@ -111,7 +112,7 @@ ScreenManager::ReleaseScreens(ScreenList& list) BAutolock locker(this); for (int32 i = 0; i < fScreenList.CountItems(); i++) { - screen_item *item = fScreenList.ItemAt(i); + screen_item* item = fScreenList.ItemAt(i); for (int32 j = 0; j < list.CountItems(); j++) { Screen* screen = list.ItemAt(j); @@ -126,7 +127,7 @@ ScreenManager::ReleaseScreens(ScreenList& list) void ScreenManager::_ScanDrivers() { - HWInterface *interface = NULL; + HWInterface* interface = NULL; // Eventually we will loop through drivers until // one can't initialize in order to support multiple monitors. @@ -155,7 +156,7 @@ ScreenManager::_ScanDrivers() void ScreenManager::_AddHWInterface(HWInterface* interface) { - Screen* screen = new(nothrow) Screen(interface, fScreenList.CountItems() + 1); + Screen* screen = new(nothrow) Screen(interface, fScreenList.CountItems()); if (screen == NULL) { delete interface; return; @@ -184,7 +185,7 @@ ScreenManager::MessageReceived(BMessage* message) { switch (message->what) { case B_NODE_MONITOR: - // ToDo: handle notification + // TODO: handle notification break; default: diff --git a/src/servers/app/ServerApp.cpp b/src/servers/app/ServerApp.cpp index e66fe0804a..98fa6320d7 100644 --- a/src/servers/app/ServerApp.cpp +++ b/src/servers/app/ServerApp.cpp @@ -615,7 +615,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) // 2) color_space space // 3) int32 bitmap_flags // 4) int32 bytes_per_row - // 5) int32 screen_id::id + // 5) int32 screen_id // Reply Data: // 1) int32 server token @@ -630,13 +630,13 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) color_space colorSpace; uint32 flags; int32 bytesPerRow; - screen_id screenID; + int32 screenID; link.Read(&frame); link.Read(&colorSpace); link.Read(&flags); link.Read(&bytesPerRow); - if (link.Read(&screenID) == B_OK) { + if (link.Read(&screenID) == B_OK) { // TODO: choose the right HWInterface with regards to the // screenID bitmap = gBitmapManager->CreateBitmap(&fMemoryAllocator, @@ -2218,10 +2218,10 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) case AS_VALID_SCREEN_ID: { // Attached data - // 1) screen_id screen - screen_id id; - if (link.Read(&id) == B_OK - && id.id == B_MAIN_SCREEN_ID.id) + // 1) int32 screen + int32 id; + if (link.Read(&id) == B_OK + && id == B_MAIN_SCREEN_ID.id) fLink.StartMessage(B_OK); else fLink.StartMessage(B_ERROR); @@ -2233,9 +2233,9 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) case AS_GET_NEXT_SCREEN_ID: { // Attached data - // 1) screen_id screen - screen_id id; - link.Read(&id); + // 1) int32 screen + int32 id; + link.Read(&id); // TODO: for now, just say we're the last one fLink.StartMessage(B_ENTRY_NOT_FOUND); @@ -2261,7 +2261,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) if (window->ClientToken() == clientToken) { // got it! fLink.StartMessage(B_OK); - fLink.Attach(B_MAIN_SCREEN_ID); + fLink.Attach(B_MAIN_SCREEN_ID.id); // TODO: for now... status = B_OK; } @@ -2278,27 +2278,19 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) { STRACE(("ServerApp %s: AS_SCREEN_GET_MODE\n", Signature())); // Attached data - // 1) screen_id screen + // 1) int32 screen // 2) uint32 workspace index - screen_id id; - link.Read(&id); + int32 id; + link.Read(&id); uint32 workspace; link.Read(&workspace); display_mode mode; - if (fDesktop->LockSingleWindow()) { - // TODO: the display_mode can be different between - // the various screens. - // We have the screen_id and the workspace number, - // with these we need to find the corresponding - // "driver", and call getmode on it - fDesktop->ScreenAt(0)->GetMode(&mode); - // actually this isn't still enough as different - // workspaces can have different display_modes - fDesktop->UnlockSingleWindow(); - } - fLink.StartMessage(B_OK); - fLink.Attach(mode); + status_t status = fDesktop->GetScreenMode(workspace, id, mode); + + fLink.StartMessage(status); + if (status == B_OK) + fLink.Attach(mode); fLink.Flush(); break; } @@ -2306,13 +2298,13 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) { STRACE(("ServerApp %s: AS_SCREEN_SET_MODE\n", Signature())); // Attached data - // 1) screen_id + // 1) int32 screen // 2) workspace index // 3) display_mode to set // 4) 'makeDefault' boolean - screen_id id; - link.Read(&id); + int32 id; + link.Read(&id); uint32 workspace; link.Read(&workspace); @@ -2323,33 +2315,10 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) bool makeDefault = false; status_t status = link.Read(&makeDefault); - if (status == B_OK && fDesktop->LockAllWindows()) { - display_mode oldMode; - // ~0 is used as the current workspace in PrivateScreen - // TODO: add constant for this - if (workspace == (uint32)~0 - || workspace == (uint32)fDesktop->CurrentWorkspace()) { - fDesktop->ScreenAt(0)->GetMode(&oldMode); - if (memcmp(&oldMode, &mode, sizeof(display_mode))) { - status = fDesktop->ScreenAt(0)->SetMode(mode, - makeDefault); - if (status == B_OK) { - fDesktop->ScreenChanged(fDesktop->ScreenAt(0), - makeDefault); - } - } else - status = B_OK; - } else { - // If you don't intend to make the screen mode the default - // for the given workspace, then you cannot change the - // configuration at all. I.e. non-default (not permanent) - // screen modes only work for the current workspace. - if (makeDefault) - fDesktop->StoreConfiguration(workspace); - } - fDesktop->UnlockAllWindows(); - } else - status = B_ERROR; + if (status == B_OK) { + status = fDesktop->SetScreenMode(workspace, id, mode, + makeDefault); + } fLink.StartMessage(status); fLink.Flush(); @@ -2359,14 +2328,15 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) case AS_PROPOSE_MODE: { STRACE(("ServerApp %s: AS_PROPOSE_MODE\n", Signature())); - screen_id id; - link.Read(&id); + int32 id; + link.Read(&id); display_mode target, low, high; link.Read(&target); link.Read(&low); link.Read(&high); - status_t status = fDesktop->HWInterface()->ProposeMode(&target, &low, &high); + status_t status = fDesktop->HWInterface()->ProposeMode(&target, + &low, &high); // ProposeMode() returns B_BAD_VALUE to hint that the candidate is // not within the given limits (but is supported) @@ -2383,13 +2353,14 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) case AS_GET_MODE_LIST: { - screen_id id; - link.Read(&id); + int32 id; + link.Read(&id); // TODO: use this screen id display_mode* modeList; uint32 count; - status_t status = fDesktop->HWInterface()->GetModeList(&modeList, &count); + status_t status = fDesktop->HWInterface()->GetModeList(&modeList, + &count); if (status == B_OK) { fLink.StartMessage(B_OK); fLink.Attach(count); @@ -2407,10 +2378,10 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) { STRACE(("ServerApp %s: AS_SCREEN_GET_COLORMAP\n", Signature())); - screen_id id; - link.Read(&id); + int32 id; + link.Read(&id); - const color_map *colorMap = SystemColorMap(); + const color_map* colorMap = SystemColorMap(); if (colorMap != NULL) { fLink.StartMessage(B_OK); fLink.Attach(*colorMap); @@ -2493,12 +2464,13 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) STRACE(("ServerApp %s: get accelerant info\n", Signature())); // We aren't using the screen_id for now... - screen_id id; - link.Read(&id); + int32 id; + link.Read(&id); accelerant_device_info accelerantInfo; // TODO: I wonder if there should be a "desktop" lock... - status_t status = fDesktop->HWInterface()->GetDeviceInfo(&accelerantInfo); + status_t status + = fDesktop->HWInterface()->GetDeviceInfo(&accelerantInfo); if (status == B_OK) { fLink.StartMessage(B_OK); fLink.Attach(accelerantInfo); @@ -2514,8 +2486,8 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) STRACE(("ServerApp %s: get monitor info\n", Signature())); // We aren't using the screen_id for now... - screen_id id; - link.Read(&id); + int32 id; + link.Read(&id); monitor_info info; // TODO: I wonder if there should be a "desktop" lock... @@ -2535,8 +2507,8 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) STRACE(("ServerApp %s: get frame buffer config\n", Signature())); // We aren't using the screen_id for now... - screen_id id; - link.Read(&id); + int32 id; + link.Read(&id); frame_buffer_config config; // TODO: I wonder if there should be a "desktop" lock... @@ -2556,8 +2528,8 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) STRACE(("ServerApp %s: get retrace semaphore\n", Signature())); // We aren't using the screen_id for now... - screen_id id; - link.Read(&id); + int32 id; + link.Read(&id); fLink.StartMessage(B_OK); fLink.Attach(fDesktop->HWInterface()->RetraceSemaphore()); @@ -2569,8 +2541,8 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) { STRACE(("ServerApp %s: get timing constraints\n", Signature())); // We aren't using the screen_id for now... - screen_id id; - link.Read(&id); + int32 id; + link.Read(&id); display_timing_constraints constraints; status_t status = fDesktop->HWInterface()->GetTimingConstraints( @@ -2589,8 +2561,8 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) { STRACE(("ServerApp %s: get pixel clock limits\n", Signature())); // We aren't using the screen_id for now... - screen_id id; - link.Read(&id); + int32 id; + link.Read(&id); display_mode mode; link.Read(&mode); @@ -2611,8 +2583,8 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) case AS_SET_DPMS: { STRACE(("ServerApp %s: AS_SET_DPMS\n", Signature())); - screen_id id; - link.Read(&id); + int32 id; + link.Read(&id); uint32 mode; link.Read(&mode); @@ -2628,8 +2600,8 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) { STRACE(("ServerApp %s: AS_GET_DPMS_STATE\n", Signature())); - screen_id id; - link.Read(&id); + int32 id; + link.Read(&id); uint32 state = fDesktop->HWInterface()->DPMSMode(); fLink.StartMessage(B_OK); @@ -2641,8 +2613,8 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) case AS_GET_DPMS_CAPABILITIES: { STRACE(("ServerApp %s: AS_GET_DPMS_CAPABILITIES\n", Signature())); - screen_id id; - link.Read(&id); + int32 id; + link.Read(&id); uint32 capabilities = fDesktop->HWInterface()->DPMSCapabilities(); fLink.StartMessage(B_OK); @@ -2679,8 +2651,8 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) case AS_GET_ACCELERANT_PATH: { - screen_id id; - fLink.Read(&id); + int32 id; + fLink.Read(&id); BString path; status_t status = fDesktop->HWInterface()->GetAccelerantPath(path); @@ -2694,8 +2666,8 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) case AS_GET_DRIVER_PATH: { - screen_id id; - fLink.Read(&id); + int32 id; + fLink.Read(&id); BString path; status_t status = fDesktop->HWInterface()->GetDriverPath(path); diff --git a/src/servers/app/ServerWindow.cpp b/src/servers/app/ServerWindow.cpp index e225f6ba31..0419e01d9d 100644 --- a/src/servers/app/ServerWindow.cpp +++ b/src/servers/app/ServerWindow.cpp @@ -123,42 +123,48 @@ static profile sRedrawProcessingTime; // TODO: Move to another file struct BufferState { BufferState(const direct_buffer_state &state) - : fState(state) + : + fState(state) { } + direct_buffer_state Action() const { return (direct_buffer_state)(fState & B_DIRECT_MODE_MASK); } + direct_buffer_state Reason() const { return (direct_buffer_state)(fState & ~B_DIRECT_MODE_MASK); - } + } + direct_buffer_state fState; }; class DirectWindowData { public: - DirectWindowData(); - ~DirectWindowData(); + DirectWindowData(); + ~DirectWindowData(); + + status_t InitCheck() const; + + status_t GetSyncData( + direct_window_sync_data& data) const; + status_t SyncronizeWithClient(); + + bool SetState(const direct_buffer_state& bufferState, + const direct_driver_state& driverState); + + BRect old_window_frame; + direct_buffer_info* buffer_info; + bool full_screen; - status_t InitCheck() const; - - status_t GetSyncData(direct_window_sync_data &data) const; - status_t SyncronizeWithClient(); - - bool SetState(const direct_buffer_state &bufferState, - const direct_driver_state &driverState); - - BRect old_window_frame; - direct_buffer_info *buffer_info; - bool full_screen; private: - sem_id fSem; - sem_id fAcknowledgeSem; - area_id fBufferArea; - direct_buffer_state fPreviousState; + sem_id fSem; + sem_id fAcknowledgeSem; + area_id fBufferArea; + direct_buffer_state fPreviousState; }; @@ -171,7 +177,7 @@ DirectWindowData::DirectWindowData() fBufferArea(-1), fPreviousState(B_DIRECT_STOP) { - fBufferArea = create_area("direct area", (void **)&buffer_info, + fBufferArea = create_area("direct area", (void**)&buffer_info, B_ANY_ADDRESS, B_PAGE_SIZE, B_NO_LOCK, B_READ_WRITE); buffer_info->buffer_state = B_DIRECT_STOP; @@ -207,12 +213,12 @@ DirectWindowData::InitCheck() const status_t -DirectWindowData::GetSyncData(direct_window_sync_data &data) const +DirectWindowData::GetSyncData(direct_window_sync_data& data) const { data.area = fBufferArea; data.disable_sem = fSem; data.disable_sem_ack = fAcknowledgeSem; - + return B_OK; } @@ -223,7 +229,7 @@ DirectWindowData::SyncronizeWithClient() // Releasing this semaphore causes the client to call // BDirectWindow::DirectConnected() status_t status = release_sem(fSem); - if (status < B_OK) + if (status != B_OK) return status; // Wait with a timeout of half a second until the client exits @@ -231,49 +237,69 @@ DirectWindowData::SyncronizeWithClient() do { status = acquire_sem_etc(fAcknowledgeSem, 1, B_TIMEOUT, 500000); } while (status == B_INTERRUPTED); - + return status; } bool -DirectWindowData::SetState(const direct_buffer_state &bufferState, - const direct_driver_state &driverState) +DirectWindowData::SetState(const direct_buffer_state& bufferState, + const direct_driver_state& driverState) { BufferState inputState(bufferState); BufferState currentState(buffer_info->buffer_state); + // Don't issue a DirectConnected() notification // if the connection is stopped, and we are called // with bufferState == B_DIRECT_MODIFY, but save the reason - // and combine it for next time we are called with B_DIRECT_START + // and combine it for next time we are called with B_DIRECT_START if (currentState.Action() == B_DIRECT_STOP - && inputState.Action() != B_DIRECT_START) { - fPreviousState = (direct_buffer_state)(fPreviousState + && inputState.Action() != B_DIRECT_START) { + fPreviousState = (direct_buffer_state)(fPreviousState | inputState.Reason()); return false; - } - - buffer_info->buffer_state = (direct_buffer_state)(bufferState + } + + buffer_info->buffer_state = (direct_buffer_state)(bufferState | BufferState(fPreviousState).Reason()); - + fPreviousState = B_DIRECT_STOP; - + if (driverState != -1) buffer_info->driver_state = driverState; - + return true; } - + +// #pragma mark - + + +#ifdef PROFILE_MESSAGE_LOOP +static int +compare_message_profiles(const void* _a, const void* _b) +{ + profile* a = (profile*)*(void**)_a; + profile* b = (profile*)*(void**)_b; + if (a->time < b->time) + return 1; + if (a->time > b->time) + return -1; + return 0; +} +#endif + + // #pragma mark - /*! Sets up the basic BWindow counterpart - you have to call Init() before you can actually use it, though. */ -ServerWindow::ServerWindow(const char *title, ServerApp *app, - port_id clientPort, port_id looperPort, int32 clientToken) - : MessageLooper(title && *title ? title : "Unnamed Window"), +ServerWindow::ServerWindow(const char* title, ServerApp* app, + port_id clientPort, port_id looperPort, int32 clientToken) + : + MessageLooper(title && *title ? title : "Unnamed Window"), fTitle(NULL), fDesktop(app->GetDesktop()), fServerApp(app), @@ -311,21 +337,6 @@ ServerWindow::ServerWindow(const char *title, ServerApp *app, } -#ifdef PROFILE_MESSAGE_LOOP -static int -compare_message_profiles(const void* _a, const void* _b) -{ - profile* a = (profile*)*(void**)_a; - profile* b = (profile*)*(void**)_b; - if (a->time < b->time) - return 1; - if (a->time > b->time) - return -1; - return 0; -} -#endif - - /*! Tears down all connections the main app_server objects, and deletes some internals. */ @@ -680,7 +691,7 @@ ServerWindow::_CreateView(BPrivate::LinkReceiver& link, View** _parent) delete newView; return NULL; } - + // there is no way of setting this, other than manually :-) newView->SetViewColor(viewColor); newView->SetHidden(hidden); @@ -3544,13 +3555,14 @@ ServerWindow::ScreenChanged(const BMessage *message) // TODO: execute the stop notification earlier //HandleDirectConnection(B_DIRECT_STOP); SendMessageToClient(message); + if (fDirectWindowData != NULL && fDirectWindowData->full_screen) { BRect screenFrame = fDesktop->ActiveScreen()->Frame(); fDesktop->ResizeWindowBy(fWindow, screenFrame.Width() - fWindow->Frame().Width(), screenFrame.Height() - fWindow->Frame().Height()); } - + //HandleDirectConnection(B_DIRECT_START | B_BUFFER_RESET, //B_SCREEN_CHANGED); } diff --git a/src/servers/app/VirtualScreen.cpp b/src/servers/app/VirtualScreen.cpp index 7e0a1b0ccc..f961d9dfda 100644 --- a/src/servers/app/VirtualScreen.cpp +++ b/src/servers/app/VirtualScreen.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2005-2007, Haiku. + * Copyright 2005-2009, Haiku. * Distributed under the terms of the MIT License. * * Authors: @@ -14,8 +14,6 @@ #include -using std::nothrow; - VirtualScreen::VirtualScreen() : @@ -44,7 +42,6 @@ VirtualScreen::_Reset() gScreenManager->ReleaseScreens(list); fScreenList.MakeEmpty(); - fSettings.MakeEmpty(); fFrame.Set(0, 0, 0, 0); fDrawingEngine = NULL; @@ -53,8 +50,8 @@ VirtualScreen::_Reset() status_t -VirtualScreen::RestoreConfiguration(Desktop& desktop, const BMessage* settings, - uint32* _changedScreens) +VirtualScreen::SetConfiguration(Desktop& desktop, + ScreenConfigurations& configurations, uint32* _changedScreens) { // Remember previous screen modes @@ -70,7 +67,7 @@ VirtualScreen::RestoreConfiguration(Desktop& desktop, const BMessage* settings, Screen* screen = fScreenList.ItemAt(i)->screen; display_mode mode; - screen->GetMode(&mode); + screen->GetMode(mode); previousModes.insert(std::make_pair(screen, mode)); } @@ -82,10 +79,6 @@ VirtualScreen::RestoreConfiguration(Desktop& desktop, const BMessage* settings, _Reset(); - // Copy current Desktop workspace settings - if (settings) - fSettings = *settings; - ScreenList list; status_t status = gScreenManager->AcquireScreens(&desktop, NULL, 0, false, list); @@ -97,12 +90,12 @@ VirtualScreen::RestoreConfiguration(Desktop& desktop, const BMessage* settings, for (int32 i = 0; i < list.CountItems(); i++) { Screen* screen = list.ItemAt(i); - AddScreen(screen); + AddScreen(screen, configurations); if (!previousModesFailed && _changedScreens != NULL) { // Figure out which screens have changed their mode display_mode mode; - screen->GetMode(&mode); + screen->GetMode(mode); ScreenModeMap::const_iterator found = previousModes.find(screen); if (found != previousModes.end() @@ -111,84 +104,30 @@ VirtualScreen::RestoreConfiguration(Desktop& desktop, const BMessage* settings, } } + UpdateFrame(); return B_OK; } status_t -VirtualScreen::StoreConfiguration(BMessage& settings) +VirtualScreen::AddScreen(Screen* screen, ScreenConfigurations& configurations) { - // store the configuration of all current screens - - for (int32 i = 0; i < fScreenList.CountItems(); i++) { - screen_item* item = fScreenList.ItemAt(i); - Screen* screen = item->screen; - if (!screen->IsDefaultMode()) - continue; - - BMessage screenSettings; - screenSettings.AddInt32("id", screen->ID()); - - monitor_info info; - if (screen->GetMonitorInfo(info) == B_OK) { - screenSettings.AddString("vendor", info.vendor); - screenSettings.AddString("name", info.name); - screenSettings.AddInt32("product id", info.product_id); - screenSettings.AddString("serial", info.serial_number); - screenSettings.AddInt32("produced week", info.produced.week); - screenSettings.AddInt32("produced year", info.produced.year); - } - - screenSettings.AddRect("frame", item->frame); - - display_mode mode; - screen->GetMode(&mode); - - screenSettings.AddData("mode", B_RAW_TYPE, &mode, - sizeof(display_mode)); - - settings.AddMessage("screen", &screenSettings); - } - - // store the configuration of all monitors currently not attached - - BMessage screenSettings; - for (uint32 i = 0; fSettings.FindMessage("screen", i, - &screenSettings) == B_OK; i++) { - settings.AddMessage("screen", &screenSettings); - } - - return B_OK; -} - - -status_t -VirtualScreen::AddScreen(Screen* screen) -{ - screen_item* item = new(nothrow) screen_item; + screen_item* item = new(std::nothrow) screen_item; if (item == NULL) return B_NO_MEMORY; item->screen = screen; status_t status = B_ERROR; - BMessage settings; - if (_GetConfiguration(screen, settings) == B_OK) { + display_mode mode; + if (_GetMode(screen, configurations, mode) == B_OK) { // we found settings for this screen, and try to apply them now - const display_mode* mode; - ssize_t size; - if (settings.FindData("mode", B_RAW_TYPE, (const void**)&mode, - &size) == B_OK - && size == sizeof(display_mode)) - status = screen->SetMode(*mode, true); - // TODO: named settings will get lost if setting the mode failed! + status = screen->SetMode(mode); } if (status != B_OK) { status_t status = screen->SetPreferredMode(); - if (status != B_OK) { - // TODO: more intelligent standard mode (desktop default, ...) + if (status != B_OK) status = screen->SetBestMode(1024, 768, B_RGB32, 60.f); - } if (status != B_OK) screen->SetBestMode(800, 600, B_RGB32, 60.f, false); } @@ -235,8 +174,7 @@ VirtualScreen::UpdateFrame() } -/*! - Returns the smallest frame that spans over all screens +/*! Returns the smallest frame that spans over all screens */ BRect VirtualScreen::Frame() const @@ -256,6 +194,20 @@ VirtualScreen::ScreenAt(int32 index) const } +Screen* +VirtualScreen::ScreenByID(int32 id) const +{ + for (int32 i = fScreenList.CountItems(); i-- > 0;) { + screen_item* item = fScreenList.ItemAt(i); + + if (item->screen->ID() == id) + return item->screen; + } + + return NULL; +} + + BRect VirtualScreen::ScreenFrameAt(int32 index) const { @@ -275,82 +227,21 @@ VirtualScreen::CountScreens() const status_t -VirtualScreen::_GetConfiguration(Screen* screen, BMessage& settings) +VirtualScreen::_GetMode(Screen* screen, ScreenConfigurations& configurations, + display_mode& mode) const { monitor_info info; bool hasInfo = screen->GetMonitorInfo(info) == B_OK; - if (!hasInfo) { - // only look for a matching ID - this is all we have - for (uint32 k = 0; k < 2; k++) { - for (uint32 i = 0; fSettings.FindMessage("screen", i, - &settings) == B_OK; i++) { - int32 id; - if (k == 0 && settings.HasString("name") - || settings.FindInt32("id", &id) != B_OK - || screen->ID() != id) - continue; - // we found our match, only remove unnamed settings - if (k == 0) - fSettings.RemoveData("screen", i); - return B_OK; - } - } + screen_configuration* configuration = configurations.BestFit(screen->ID(), + hasInfo ? &info : NULL); + if (configuration == NULL) return B_NAME_NOT_FOUND; - } - // look for a monitor configuration that matches ours + mode = configuration->mode; +debug_printf("found configuration! (%d x %d)\n", mode.virtual_width, mode.virtual_height); + configuration->is_current = true; - bool exactMatch = false; - int32 bestScore = 0; - int32 bestIndex = -1; - BMessage stored; - for (uint32 i = 0; fSettings.FindMessage("screen", i, &stored) == B_OK; - i++) { - // TODO: should we ignore unnamed settings here completely? - int32 score = 0; - int32 id; - if (stored.FindInt32("id", &id) == B_OK && screen->ID() == id) - score++; - - const char* vendor; - const char* name; - uint32 productID; - const char* serial; - int32 week, year; - if (stored.FindString("vendor", &vendor) == B_OK - && stored.FindString("name", &name) == B_OK - && stored.FindInt32("product id", (int32*)&productID) == B_OK - && stored.FindString("serial", &serial) == B_OK - && stored.FindInt32("produced week", &week) == B_OK - && stored.FindInt32("produced year", &year) == B_OK) { - if (!strcasecmp(vendor, info.vendor) - && !strcasecmp(name, info.name) - && productID == info.product_id) { - score += 2; - if (!strcmp(serial, info.serial_number)) { - exactMatch = true; - score += 2; - } - if (info.produced.year == year && info.produced.week == week) - score++; - } else - score -= 2; - } - - if (score > bestScore) { - settings = stored; - bestScore = score; - bestIndex = i; - } - } - - if (bestIndex >= 0) { - if (exactMatch) - fSettings.RemoveData("screen", bestIndex); - return B_OK; - } - - return B_NAME_NOT_FOUND; + return B_OK; } diff --git a/src/servers/app/VirtualScreen.h b/src/servers/app/VirtualScreen.h index 9845186aec..b370add7b1 100644 --- a/src/servers/app/VirtualScreen.h +++ b/src/servers/app/VirtualScreen.h @@ -1,5 +1,5 @@ /* - * Copyright 2005-2007, Haiku. + * Copyright 2005-2009, Haiku. * Distributed under the terms of the MIT License. * * Authors: @@ -9,63 +9,67 @@ #define VIRTUAL_SCREEN_H +#include "ScreenConfigurations.h" #include "ScreenManager.h" #include + class Desktop; class DrawingEngine; class HWInterface; class VirtualScreen { - public: - VirtualScreen(); - ~VirtualScreen(); +public: + VirtualScreen(); + ~VirtualScreen(); - ::DrawingEngine* DrawingEngine() const - { return fDrawingEngine; } - // TODO: can we have a multiplexing HWInterface as well? - // If not, this would need to be hidden, and only made - // available for the Screen class - ::HWInterface* HWInterface() const - { return fHWInterface; } + ::DrawingEngine* DrawingEngine() const + { return fDrawingEngine; } - status_t RestoreConfiguration(Desktop& desktop, - const BMessage* settings, - uint32* _changedScreens = NULL); - status_t StoreConfiguration(BMessage& settings); + // TODO: can we have a multiplexing HWInterface as well? + // If not, this would need to be hidden, and only made + // available for the Screen class + ::HWInterface* HWInterface() const + { return fHWInterface; } - status_t AddScreen(Screen* screen); - status_t RemoveScreen(Screen* screen); + status_t SetConfiguration(Desktop& desktop, + ScreenConfigurations& configurations, + uint32* _changedScreens = NULL); - void UpdateFrame(); - BRect Frame() const; + status_t AddScreen(Screen* screen, + ScreenConfigurations& configurations); + status_t RemoveScreen(Screen* screen); - // TODO: we need to play with a real multi-screen configuration to - // figure out the specifics here - possibly in the test environment? - void SetScreenFrame(int32 index, BRect frame); + void UpdateFrame(); + BRect Frame() const; - Screen* ScreenAt(int32 index) const; - BRect ScreenFrameAt(int32 index) const; - int32 CountScreens() const; + // TODO: we need to play with a real multi-screen configuration to + // figure out the specifics here + void SetScreenFrame(int32 index, BRect frame); - private: - status_t _GetConfiguration(Screen* screen, - BMessage& settings); - void _Reset(); + Screen* ScreenAt(int32 index) const; + Screen* ScreenByID(int32 id) const; + BRect ScreenFrameAt(int32 index) const; + int32 CountScreens() const; - struct screen_item { - Screen* screen; - BRect frame; - // TODO: do we want to have a different color per screen as well? - }; +private: + status_t _GetMode(Screen* screen, + ScreenConfigurations& configurations, + display_mode& mode) const; + void _Reset(); - BMessage fSettings; - BRect fFrame; - BObjectList fScreenList; - ::DrawingEngine* fDrawingEngine; - ::HWInterface* fHWInterface; + struct screen_item { + Screen* screen; + BRect frame; + // TODO: do we want to have a different color per screen as well? + }; + + BRect fFrame; + BObjectList fScreenList; + ::DrawingEngine* fDrawingEngine; + ::HWInterface* fHWInterface; }; #endif /* VIRTUAL_SCREEN_H */ diff --git a/src/servers/app/Workspace.cpp b/src/servers/app/Workspace.cpp index 3c12bc872b..617ecba1e1 100644 --- a/src/servers/app/Workspace.cpp +++ b/src/servers/app/Workspace.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2005-2008, Haiku. + * Copyright 2005-2009, Haiku. * Distributed under the terms of the MIT License. * * Authors: @@ -50,16 +50,18 @@ Workspace::Private::RestoreConfiguration(const BMessage& settings) rgb_color color; if (settings.FindInt32("color", (int32 *)&color) == B_OK) fColor = color; + + fStoredScreenConfiguration.Restore(settings); + fCurrentScreenConfiguration.Restore(settings); } -/*! - \brief Store the workspace configuration in a message +/*! \brief Store the workspace configuration in a message */ void Workspace::Private::StoreConfiguration(BMessage& settings) { - settings.RemoveName("color"); + fStoredScreenConfiguration.Store(settings); settings.AddInt32("color", *(int32 *)&fColor); } @@ -80,18 +82,13 @@ Workspace::Workspace(Desktop& desktop, int32 index) fDesktop(desktop), fCurrentWorkspace(index == desktop.CurrentWorkspace()) { -// fDesktop.LockSingleWindow(); - // TODO: in which threads is this being used? - // from my investigations, it is used in the - // WorkspacesView::Draw(), which would have - // to hold the read lock already + ASSERT_MULTI_LOCKED(desktop.WindowLocker()); RewindWindows(); } Workspace::~Workspace() { -// fDesktop.UnlockSingleWindow(); } diff --git a/src/servers/app/Workspace.h b/src/servers/app/Workspace.h index 152f277655..4921133092 100644 --- a/src/servers/app/Workspace.h +++ b/src/servers/app/Workspace.h @@ -1,5 +1,5 @@ /* - * Copyright 2005-2008, Haiku. + * Copyright 2005-2009, Haiku. * Distributed under the terms of the MIT License. * * Authors: @@ -17,26 +17,29 @@ class Window; class Workspace { - public: - Workspace(Desktop& desktop, int32 index); - ~Workspace(); +public: + Workspace(Desktop& desktop, int32 index); + ~Workspace(); - const rgb_color& Color() const; - void SetColor(const rgb_color& color, bool makeDefault); - bool IsCurrent() const - { return fCurrentWorkspace; } + const rgb_color& Color() const; + void SetColor(const rgb_color& color, + bool makeDefault); + bool IsCurrent() const + { return fCurrentWorkspace; } - status_t GetNextWindow(Window*& _window, BPoint& _leftTop); - status_t GetPreviousWindow(Window*& _window, BPoint& _leftTop); - void RewindWindows(); + status_t GetNextWindow(Window*& _window, + BPoint& _leftTop); + status_t GetPreviousWindow(Window*& _window, + BPoint& _leftTop); + void RewindWindows(); - class Private; + class Private; - private: - Workspace::Private& fWorkspace; - Desktop& fDesktop; - Window* fCurrent; - bool fCurrentWorkspace; +private: + Workspace::Private& fWorkspace; + Desktop& fDesktop; + Window* fCurrent; + bool fCurrentWorkspace; }; #endif /* WORKSPACE_H */ diff --git a/src/servers/app/WorkspacePrivate.h b/src/servers/app/WorkspacePrivate.h index 58cc220286..2376b96695 100644 --- a/src/servers/app/WorkspacePrivate.h +++ b/src/servers/app/WorkspacePrivate.h @@ -1,5 +1,5 @@ /* - * Copyright 2005-2008, Haiku. + * Copyright 2005-2009, Haiku. * Distributed under the terms of the MIT License. * * Authors: @@ -9,6 +9,7 @@ #define WORKSPACE_PRIVATE_H +#include "ScreenConfigurations.h" #include "WindowList.h" #include "Workspace.h" @@ -23,40 +24,50 @@ struct display_info { display_mode mode; }; + class Workspace::Private { - public: - Private(); - ~Private(); +public: + Private(); + ~Private(); - int32 Index() const { return fWindows.Index(); } + int32 Index() const { return fWindows.Index(); } - WindowList& Windows() { return fWindows; } + WindowList& Windows() { return fWindows; } - // displays + // displays - void SetDisplaysFromDesktop(Desktop* desktop); + void SetDisplaysFromDesktop(Desktop* desktop); - int32 CountDisplays() const { return fDisplays.CountItems(); } - const display_info* DisplayAt(int32 index) const { return fDisplays.ItemAt(index); } + int32 CountDisplays() const + { return fDisplays.CountItems(); } + const display_info* DisplayAt(int32 index) const + { return fDisplays.ItemAt(index); } - // configuration + // configuration - const rgb_color& Color() const { return fColor; } - void SetColor(const rgb_color& color); + const rgb_color& Color() const { return fColor; } + void SetColor(const rgb_color& color); - void RestoreConfiguration(const BMessage& settings); - void StoreConfiguration(BMessage& settings); + ScreenConfigurations& CurrentScreenConfiguration() + { return fCurrentScreenConfiguration; } + ScreenConfigurations& StoredScreenConfiguration() + { return fStoredScreenConfiguration; } - private: - void _SetDefaults(); + void RestoreConfiguration(const BMessage& settings); + void StoreConfiguration(BMessage& settings); - WindowList fWindows; - Window* fFront; - Window* fFocus; +private: + void _SetDefaults(); - BObjectList fDisplays; + WindowList fWindows; + Window* fFront; + Window* fFocus; - rgb_color fColor; + BObjectList fDisplays; + + ScreenConfigurations fStoredScreenConfiguration; + ScreenConfigurations fCurrentScreenConfiguration; + rgb_color fColor; }; #endif /* WORKSPACE_PRIVATE_H */