From 4b0459b2eef38f07b8c0c4426860dccb61a1134a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Wed, 4 Nov 2009 14:08:16 +0000 Subject: [PATCH] * Refactored ServerBitmap a bit: it now inherits from Referenceable instead of roling its own solution. * Also removed BitmapManager::DeleteBitmap() - you only call ServerBitmap::RemoveReference(), and that one will notify the manager if needed. * Some more cleanup. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@33878 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/servers/app/BitmapManager.cpp | 17 +-- src/servers/app/BitmapManager.h | 3 +- src/servers/app/CursorManager.cpp | 88 +++++------- src/servers/app/EventDispatcher.cpp | 15 +- src/servers/app/OffscreenServerWindow.cpp | 2 +- src/servers/app/ServerApp.cpp | 28 ++-- src/servers/app/ServerBitmap.cpp | 45 +++--- src/servers/app/ServerBitmap.h | 13 +- src/servers/app/ServerCursor.cpp | 77 +++++------ src/servers/app/ServerCursor.h | 161 ++++++++++++---------- src/servers/app/ServerWindow.cpp | 8 +- src/servers/app/View.cpp | 12 +- src/servers/app/drawing/HWInterface.cpp | 4 +- 13 files changed, 215 insertions(+), 258 deletions(-) diff --git a/src/servers/app/BitmapManager.cpp b/src/servers/app/BitmapManager.cpp index 27702fe688..e10496d3a2 100644 --- a/src/servers/app/BitmapManager.cpp +++ b/src/servers/app/BitmapManager.cpp @@ -201,18 +201,11 @@ BitmapManager::CreateBitmap(ClientMemoryAllocator* allocator, } -/*! \brief Deletes a ServerBitmap. - \param bitmap The bitmap to delete +/*! \brief Called when a ServerBitmap is deleted. */ void -BitmapManager::DeleteBitmap(ServerBitmap* bitmap) +BitmapManager::BitmapRemoved(ServerBitmap* bitmap) { - if (bitmap == NULL || !bitmap->_Release()) { - // there are other references to this bitmap, we don't have to delete - // it yet - return; - } - BAutolock locker(fLock); if (!locker.IsLocked()) return; @@ -220,11 +213,7 @@ BitmapManager::DeleteBitmap(ServerBitmap* bitmap) if (bitmap->Overlay() != NULL) fOverlays.RemoveItem(bitmap); - if (bitmap->Owner() != NULL) - bitmap->Owner()->BitmapRemoved(bitmap); - - if (fBitmapList.RemoveItem(bitmap)) - delete bitmap; + fBitmapList.RemoveItem(bitmap); } diff --git a/src/servers/app/BitmapManager.h b/src/servers/app/BitmapManager.h index 7f444c1618..9459e9adbe 100644 --- a/src/servers/app/BitmapManager.h +++ b/src/servers/app/BitmapManager.h @@ -32,7 +32,8 @@ public: int32 bytesPerRow = -1, int32 screen = B_MAIN_SCREEN_ID.id, uint8* _allocationFlags = NULL); - void DeleteBitmap(ServerBitmap* bitmap); + + void BitmapRemoved(ServerBitmap* bitmap); void SuspendOverlays(); void ResumeOverlays(); diff --git a/src/servers/app/CursorManager.cpp b/src/servers/app/CursorManager.cpp index 72d9b8d5b2..bab27b360b 100644 --- a/src/servers/app/CursorManager.cpp +++ b/src/servers/app/CursorManager.cpp @@ -1,12 +1,14 @@ /* - * Copyright 2001-2006, Haiku. + * Copyright 2001-2009, Haiku. * Distributed under the terms of the MIT License. * * Authors: * DarkWyrm */ -/** Handles the system's cursor infrastructure */ + +/*! Handles the system's cursor infrastructure */ + #include "CursorManager.h" @@ -25,7 +27,8 @@ CursorManager::CursorManager() - : BLocker("CursorManager") + : + BLocker("CursorManager") { // Set system cursors to "unassigned" // ToDo: decide about default cursor @@ -74,6 +77,7 @@ CursorManager::~CursorManager() } } + ServerCursor* CursorManager::CreateCursor(team_id clientTeam, const uint8* cursorData) { @@ -92,17 +96,16 @@ CursorManager::CreateCursor(team_id clientTeam, const uint8* cursorData) } } } else { - cursor->Acquire(); + cursor->AcquireReference(); } Unlock(); - + return cursor; } -/*! - \brief Registers a cursor with the manager. +/*! \brief Registers a cursor with the manager. \param cursor ServerCursor object to register \return The token assigned to the cursor or B_ERROR if cursor is NULL */ @@ -132,8 +135,7 @@ CursorManager::AddCursor(ServerCursor* cursor, int32 token) } -/*! - \brief Removes a cursor if it's not referenced anymore. +/*! \brief Removes a cursor if it's not referenced anymore. If this was the last reference to this cursor, it will be deleted. Only if the cursor is deleted, \c true is returned. @@ -145,7 +147,7 @@ CursorManager::RemoveCursor(ServerCursor* cursor) return false; // TODO: this doesn't work as it looks like, and it's not safe! - if (cursor->ReferenceCount() > 0) { + if (cursor->CountReferences() > 0) { // cursor has been referenced again in the mean time Unlock(); return false; @@ -158,8 +160,7 @@ CursorManager::RemoveCursor(ServerCursor* cursor) } -/*! - \brief Removes and deletes all of an application's cursors +/*! \brief Removes and deletes all of an application's cursors \param signature Signature to which the cursors belong */ void @@ -171,17 +172,16 @@ CursorManager::DeleteCursors(team_id team) for (int32 index = fCursorList.CountItems(); index-- > 0;) { ServerCursor *cursor = (ServerCursor*)fCursorList.ItemAtFast(index); if (cursor->OwningTeam() == team) - cursor->Release(); + cursor->ReleaseReference(); } Unlock(); } -/*! - \brief Sets all the cursors from a specified CursorSet +/*! \brief Sets all the cursors from a specified CursorSet \param path Path to the cursor set - + All cursors in the set will be assigned. If the set does not specify a cursor for a particular cursor specifier, it will remain unchanged. This function will fail if passed a NULL path, an invalid path, or the @@ -200,65 +200,55 @@ CursorManager::SetCursorSet(const char *path) ServerCursor *cursor = NULL; if (cursorSet.FindCursor(B_CURSOR_DEFAULT, &cursor) == B_OK) { - if (fDefaultCursor) - delete fDefaultCursor; + delete fDefaultCursor; fDefaultCursor = cursor; } if (cursorSet.FindCursor(B_CURSOR_TEXT, &cursor) == B_OK) { - if (fTextCursor) - delete fTextCursor; + delete fTextCursor; fTextCursor = cursor; } if (cursorSet.FindCursor(B_CURSOR_MOVE, &cursor) == B_OK) { - if (fMoveCursor) - delete fMoveCursor; + delete fMoveCursor; fMoveCursor = cursor; } if (cursorSet.FindCursor(B_CURSOR_DRAG, &cursor) == B_OK) { - if (fDragCursor) - delete fDragCursor; + delete fDragCursor; fDragCursor = cursor; } if (cursorSet.FindCursor(B_CURSOR_RESIZE, &cursor) == B_OK) { - if (fResizeCursor) - delete fResizeCursor; + delete fResizeCursor; fResizeCursor = cursor; } if (cursorSet.FindCursor(B_CURSOR_RESIZE_NWSE, &cursor) == B_OK) { - if (fNWSECursor) - delete fNWSECursor; + delete fNWSECursor; fNWSECursor = cursor; } if (cursorSet.FindCursor(B_CURSOR_RESIZE_NESW, &cursor) == B_OK) { - if (fNESWCursor) - delete fNESWCursor; + delete fNESWCursor; fNESWCursor = cursor; } if (cursorSet.FindCursor(B_CURSOR_RESIZE_NS, &cursor) == B_OK) { - if (fNSCursor) - delete fNSCursor; + delete fNSCursor; fNSCursor = cursor; } if (cursorSet.FindCursor(B_CURSOR_RESIZE_EW, &cursor) == B_OK) { - if (fEWCursor) - delete fEWCursor; + delete fEWCursor; fEWCursor = cursor; } } -/*! - \brief Acquire the cursor which is used for a particular system cursor +/*! \brief Acquire the cursor which is used for a particular system cursor \param which Which system cursor to get - \return Pointer to the particular cursor used or NULL if which is + \return Pointer to the particular cursor used or NULL if which is invalid or the cursor has not been assigned */ ServerCursor * @@ -292,8 +282,7 @@ CursorManager::GetCursor(cursor_which which) } -/*! - \brief Gets the current system cursor value +/*! \brief Gets the current system cursor value \return The current cursor value or CURSOR_OTHER if some non-system cursor */ cursor_which @@ -310,11 +299,10 @@ CursorManager::GetCursorWhich() } -/*! - \brief Sets the specified system cursor to the a particular cursor +/*! \brief Sets the specified system cursor to the a particular cursor \param which Which system cursor to change \param token The ID of the cursor to become the new one - + A word of warning: once a cursor has been assigned to the system, the system will take ownership of the cursor and deleting the cursor will have no effect on the system. @@ -420,8 +408,7 @@ CursorManager::SetDefaults() } -/*! - \brief Internal function which finds the cursor with a particular ID +/*! \brief Internal function which finds the cursor with a particular ID \param token ID of the cursor to find \return The cursor or NULL if not found */ @@ -464,16 +451,3 @@ CursorManager::_RemoveCursor(ServerCursor* cursor) fCursorList.RemoveItem(cursor); fTokenSpace.RemoveToken(cursor->fToken); } - - -//ServerCursor* -//CursorManager::_RemoveCursor(int32 index) -//{ -// ServerCursor* cursor = (ServerCursor*)fCursorList.RemoveItem(index); -// if (cursor != NULL) -// fTokenSpace.RemoveToken(cursor->fToken); -// -// return cursor; -//} - - diff --git a/src/servers/app/EventDispatcher.cpp b/src/servers/app/EventDispatcher.cpp index 818e2a8c0d..0ea0cdaa66 100644 --- a/src/servers/app/EventDispatcher.cpp +++ b/src/servers/app/EventDispatcher.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2005-2008, Haiku, Inc. All Rights Reserved. + * Copyright 2005-2009, Haiku, Inc. All Rights Reserved. * Distributed under the terms of the MIT License. * * Authors: @@ -606,17 +606,18 @@ EventDispatcher::SetDragMessage(BMessage& message, if (fLastButtons == 0) { // mouse buttons has already been released or was never pressed - gBitmapManager->DeleteBitmap(bitmap); + bitmap->ReleaseReference(); return; } if (fDragBitmap != bitmap) { if (fDragBitmap) - gBitmapManager->DeleteBitmap(fDragBitmap); + fDragBitmap->ReleaseReference(); + fDragBitmap = bitmap; if (fDragBitmap != NULL) - fDragBitmap->Acquire(); + fDragBitmap->AcquireReference(); } fHWInterface->SetDragBitmap(bitmap, offsetFromCursor); @@ -749,8 +750,10 @@ EventDispatcher::_DeliverDragMessage() fDraggingMessage = false; fHWInterface->SetDragBitmap(NULL, B_ORIGIN); - gBitmapManager->DeleteBitmap(fDragBitmap); - fDragBitmap = NULL; + if (fDragBitmap != NULL) { + fDragBitmap->ReleaseReference(); + fDragBitmap = NULL; + } } diff --git a/src/servers/app/OffscreenServerWindow.cpp b/src/servers/app/OffscreenServerWindow.cpp index d6121610a9..102ed01e95 100644 --- a/src/servers/app/OffscreenServerWindow.cpp +++ b/src/servers/app/OffscreenServerWindow.cpp @@ -24,7 +24,7 @@ OffscreenServerWindow::OffscreenServerWindow(const char *title, ServerApp *app, OffscreenServerWindow::~OffscreenServerWindow() { - fBitmap->Release(); + fBitmap->ReleaseReference(); } diff --git a/src/servers/app/ServerApp.cpp b/src/servers/app/ServerApp.cpp index df41219dd2..38606ae4e2 100644 --- a/src/servers/app/ServerApp.cpp +++ b/src/servers/app/ServerApp.cpp @@ -195,7 +195,7 @@ ServerApp::~ServerApp() ServerBitmap* bitmap = fBitmapMap.begin()->second; fBitmapMap.erase(fBitmapMap.begin()); - bitmap->Release(); + bitmap->ReleaseReference(); } while (!fPictureMap.empty()) { @@ -302,12 +302,12 @@ ServerApp::SetCurrentCursor(ServerCursor* cursor) return; if (fViewCursor) - fViewCursor->Release(); + fViewCursor->ReleaseReference(); fViewCursor = cursor; if (fViewCursor) - fViewCursor->Acquire(); + fViewCursor->AcquireReference(); fDesktop->SetCursor(CurrentCursor()); } @@ -413,7 +413,7 @@ ServerApp::GetBitmap(int32 token) const if (bitmap == NULL) return NULL; - bitmap->Acquire(); + bitmap->AcquireReference(); return bitmap; } @@ -757,7 +757,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) fLink.Attach(bitmap->BytesPerRow()); } else { if (bitmap != NULL) - bitmap->Release(); + bitmap->ReleaseReference(); fLink.StartMessage(B_NO_MEMORY); } @@ -784,7 +784,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) STRACE(("ServerApp %s: Deleting Bitmap %ld\n", Signature(), token)); - bitmap->Release(); + bitmap->ReleaseReference(); } fMapLocker.Unlock(); @@ -807,7 +807,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) status = fDesktop->HWInterface()->GetOverlayRestrictions( bitmap->Overlay(), &restrictions); - bitmap->Release(); + bitmap->ReleaseReference(); } fLink.StartMessage(status); @@ -1031,13 +1031,13 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) ServerCursor* oldCursor = fAppCursor; fAppCursor = fDesktop->GetCursorManager().FindCursor(token); if (fAppCursor != NULL) - fAppCursor->Acquire(); + fAppCursor->AcquireReference(); if (_HasWindowUnderMouse()) fDesktop->SetCursor(CurrentCursor()); if (oldCursor != NULL) - oldCursor->Release(); + oldCursor->ReleaseReference(); fDesktop->GetCursorManager().Unlock(); @@ -1063,7 +1063,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) // get a NULL cursor, it probably means we are supposed to use // the system default cursor. if (cursor != NULL) - cursor->Acquire(); + cursor->AcquireReference(); fDesktop->GetCursorManager().Unlock(); @@ -1094,7 +1094,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) // Release the temporary reference. if (cursor != NULL) - cursor->Release(); + cursor->ReleaseReference(); } if (info.sync) { @@ -1164,7 +1164,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) ServerCursor* cursor = fDesktop->GetCursorManager().FindCursor(token); if (cursor != NULL) - cursor->Acquire(); + cursor->AcquireReference(); fDesktop->GetCursorManager().Unlock(); @@ -1185,7 +1185,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) ServerCursor* cursor = fDesktop->GetCursorManager().FindCursor(token); if (cursor != NULL) - cursor->Release(); + cursor->ReleaseReference(); fDesktop->GetCursorManager().Unlock(); @@ -2861,7 +2861,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) } else fLink.StartMessage(B_BAD_VALUE); - gBitmapManager->DeleteBitmap(bitmap); + bitmap->ReleaseReference(); } else fLink.StartMessage(B_BAD_VALUE); diff --git a/src/servers/app/ServerBitmap.cpp b/src/servers/app/ServerBitmap.cpp index 5e32379046..f3476c8ccc 100644 --- a/src/servers/app/ServerBitmap.cpp +++ b/src/servers/app/ServerBitmap.cpp @@ -123,42 +123,18 @@ ServerBitmap::~ServerBitmap() } -void -ServerBitmap::Acquire() -{ - atomic_add(&fReferenceCount, 1); -} - - -void -ServerBitmap::Release() -{ - gBitmapManager->DeleteBitmap(this); -} - - -bool -ServerBitmap::_Release() -{ - if (atomic_add(&fReferenceCount, -1) == 1) - return true; - - return false; -} - - /*! \brief Internal function used by subclasses Subclasses should call this so the buffer can automagically be allocated on the heap. */ void -ServerBitmap::_AllocateBuffer(void) +ServerBitmap::AllocateBuffer() { uint32 length = BitsLength(); if (length > 0) { delete[] fBuffer; - fBuffer = new(nothrow) uint8[length]; + fBuffer = new(std::nothrow) uint8[length]; } } @@ -252,6 +228,17 @@ ServerBitmap::PrintToStream() } +void +ServerBitmap::LastReferenceReleased() +{ + if (fOwner != NULL) + fOwner->BitmapRemoved(this); + + gBitmapManager->BitmapRemoved(this); + delete this; +} + + // #pragma mark - @@ -259,14 +246,14 @@ UtilityBitmap::UtilityBitmap(BRect rect, color_space space, uint32 flags, int32 bytesperline, screen_id screen) : ServerBitmap(rect, space, flags, bytesperline, screen) { - _AllocateBuffer(); + AllocateBuffer(); } UtilityBitmap::UtilityBitmap(const ServerBitmap* bitmap) : ServerBitmap(bitmap) { - _AllocateBuffer(); + AllocateBuffer(); if (bitmap->Bits()) memcpy(Bits(), bitmap->Bits(), bitmap->BitsLength()); @@ -277,7 +264,7 @@ UtilityBitmap::UtilityBitmap(const uint8* alreadyPaddedData, uint32 width, uint32 height, color_space format) : ServerBitmap(BRect(0, 0, width - 1, height - 1), format, 0) { - _AllocateBuffer(); + AllocateBuffer(); if (Bits()) memcpy(Bits(), alreadyPaddedData, BitsLength()); } diff --git a/src/servers/app/ServerBitmap.h b/src/servers/app/ServerBitmap.h index 638ce909e8..d1a5de7118 100644 --- a/src/servers/app/ServerBitmap.h +++ b/src/servers/app/ServerBitmap.h @@ -14,6 +14,9 @@ #include #include +#include + + class BitmapManager; class ClientMemoryAllocator; class HWInterface; @@ -28,14 +31,11 @@ class ServerApp; managed by the BitmapManager class. It is also the base class for all cursors. Every BBitmap has a shadow ServerBitmap object. */ -class ServerBitmap { +class ServerBitmap : public Referenceable { public: inline bool IsValid() const { return fBuffer != NULL; } - void Acquire(); - void Release(); - inline uint8* Bits() const { return fBuffer; } inline uint32 BitsLength() const @@ -93,10 +93,11 @@ protected: ServerBitmap(const ServerBitmap* bmp); virtual ~ServerBitmap(); - bool _Release(); + virtual void LastReferenceReleased(); - void _AllocateBuffer(); + void AllocateBuffer(); +protected: ClientMemoryAllocator* fAllocator; void* fAllocationCookie; ::Overlay* fOverlay; diff --git a/src/servers/app/ServerCursor.cpp b/src/servers/app/ServerCursor.cpp index 735db850bf..a34e06b408 100644 --- a/src/servers/app/ServerCursor.cpp +++ b/src/servers/app/ServerCursor.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2001-2006, Haiku. + * Copyright 2001-2009, Haiku. * Distributed under the terms of the MIT License. * * Authors: @@ -8,13 +8,16 @@ * Axel Dörfler, axeld@pinc-software.de */ -/*! - Although descended from ServerBitmaps, ServerCursors are not handled by - the BitmapManager - they are allocated like any other object. Unlike BeOS - R5, cursors can be any size or color space, and this class accomodates and - expands the R5 API. + +/*! Although descended from ServerBitmaps, ServerCursors are not handled by + the BitmapManager, but the CursorManager instead. Until they have been + attached to a CursorManager, you can delete cursors like any other object. + + Unlike BeOS, cursors can be any size or color space, and this class + accomodates and expands the BeOS API. */ + #include "CursorManager.h" #include "ServerCursor.h" @@ -26,13 +29,15 @@ using std::nothrow; -/*! - \brief Constructor + +/*! \brief Constructor + \param r Size of the cursor \param cspace Color space of the cursor \param flags ServerBitmap flags. See Bitmap.h. \param hotspot Hotspot of the cursor - \param bytesperline Bytes per row for the cursor. See ServerBitmap::ServerBitmap() + \param bytesperline Bytes per row for the cursor. See + ServerBitmap::ServerBitmap() */ ServerCursor::ServerCursor(BRect r, color_space format, int32 flags, @@ -41,37 +46,36 @@ ServerCursor::ServerCursor(BRect r, color_space format, int32 flags, ServerBitmap(r, format, flags, bytesPerRow, screen), fHotSpot(hotspot), fOwningTeam(-1), - fReferenceCount(1), fCursorData(NULL), fManager(NULL) { fHotSpot.ConstrainTo(Bounds()); - _AllocateBuffer(); + AllocateBuffer(); } -/*! - \brief Constructor - \param data Pointer to 68-byte cursor data array. See BeBook entry for BCursor for details +/*! \brief Constructor + \param data Pointer to 68-byte cursor data array. See BeBook entry for + BCursor for details */ ServerCursor::ServerCursor(const uint8* data) : ServerBitmap(BRect(0, 0, 15, 15), B_RGBA32, 0), fHotSpot(0, 0), fOwningTeam(-1), - fReferenceCount(1), fCursorData(NULL), fManager(NULL) { - // 68-byte array used in R5 for holding cursors. - // This API has serious problems and should be deprecated(but supported) in R2 + // 68-byte array used in BeOS for holding cursors. + // This API has serious problems and should be deprecated (but supported) + // in R2 // Now that we have all the setup, we're going to map (for now) the cursor // to RGBA32 (little endian). Eventually, there will be support for 16 and // 8-bit depths // NOTE: review this once we have working PPC graphics cards (big endian). if (data) { - _AllocateBuffer(); + AllocateBuffer(); uint8* buffer = Bits(); if (!buffer) return; @@ -116,8 +120,7 @@ ServerCursor::ServerCursor(const uint8* data) } -/*! - \brief Constructor +/*! \brief Constructor \param data Pointer to bitmap data in memory, the padding bytes should be contained when format less than 32 bpp. */ @@ -127,18 +130,16 @@ ServerCursor::ServerCursor(const uint8* alreadyPaddedData, uint32 width, ServerBitmap(BRect(0, 0, width - 1, height - 1), format, 0), fHotSpot(0, 0), fOwningTeam(-1), - fReferenceCount(1), fCursorData(NULL), fManager(NULL) { - _AllocateBuffer(); + AllocateBuffer(); if (Bits()) memcpy(Bits(), alreadyPaddedData, BitsLength()); } -/*! - \brief Copy constructor +/*! \brief Copy constructor \param cursor cursor to copy */ ServerCursor::ServerCursor(const ServerCursor* cursor) @@ -146,13 +147,12 @@ ServerCursor::ServerCursor(const ServerCursor* cursor) ServerBitmap(cursor), fHotSpot(0, 0), fOwningTeam(-1), - fReferenceCount(1), fCursorData(NULL), fManager(NULL) { // TODO: Hm. I don't move this into the if clause, // because it might break code elsewhere. - _AllocateBuffer(); + AllocateBuffer(); if (cursor) { if (Bits() && cursor->Bits()) @@ -174,8 +174,7 @@ ServerCursor::~ServerCursor() } -/*! - \brief Sets the cursor's hotspot +/*! \brief Sets the cursor's hotspot \param pt New location of hotspot, constrained to the cursor's boundaries. */ void @@ -186,23 +185,17 @@ ServerCursor::SetHotSpot(BPoint hotSpot) } -bool -ServerCursor::Release() -{ - if (atomic_add(&fReferenceCount, -1) == 1) { - if (fManager && !fManager->RemoveCursor(this)) - return false; - - delete this; - return true; - } - return false; -} - - void ServerCursor::AttachedToManager(CursorManager* manager) { fManager = manager; } + +void +ServerCursor::LastReferenceReleased() +{ + if (fManager != NULL && fManager->RemoveCursor(this)) + delete this; +} + diff --git a/src/servers/app/ServerCursor.h b/src/servers/app/ServerCursor.h index 40ac712205..e6d7b2a2b3 100644 --- a/src/servers/app/ServerCursor.h +++ b/src/servers/app/ServerCursor.h @@ -1,5 +1,5 @@ /* - * Copyright 2001-2006, Haiku. + * Copyright 2001-2009, Haiku. * Distributed under the terms of the MIT License. * * Authors: @@ -16,103 +16,112 @@ #include #include -class ServerApp; + class CursorManager; class ServerCursor : public ServerBitmap { - public: - ServerCursor(BRect r, color_space space, - int32 flags, BPoint hotspot, - int32 bytesperrow = -1, - screen_id screen = B_MAIN_SCREEN_ID); - ServerCursor(const uint8* cursorDataFromR5); - ServerCursor(const uint8* alreadyPaddedData, - uint32 width, uint32 height, - color_space format); - ServerCursor(const ServerCursor* cursor); +public: + ServerCursor(BRect r, color_space space, + int32 flags, BPoint hotspot, + int32 bytesPerRow = -1, + screen_id screen = B_MAIN_SCREEN_ID); + ServerCursor(const uint8* cursorDataFromR5); + ServerCursor(const uint8* alreadyPaddedData, + uint32 width, uint32 height, + color_space format); + ServerCursor(const ServerCursor* cursor); - virtual ~ServerCursor(); + virtual ~ServerCursor(); //! Returns the cursor's hot spot - void SetHotSpot(BPoint pt); - BPoint GetHotSpot() const - { return fHotSpot; } + void SetHotSpot(BPoint pt); + BPoint GetHotSpot() const + { return fHotSpot; } - void SetOwningTeam(team_id tid) - { fOwningTeam = tid; } - team_id OwningTeam() const - { return fOwningTeam; } + void SetOwningTeam(team_id tid) + { fOwningTeam = tid; } + team_id OwningTeam() const + { return fOwningTeam; } - int32 Token() const - { return fToken; } + int32 Token() const + { return fToken; } - void Acquire() - { atomic_add(&fReferenceCount, 1); } - bool Release(); - int32 ReferenceCount() { return fReferenceCount; } + void AttachedToManager(CursorManager* manager); - void AttachedToManager(CursorManager* manager); + const uint8* CursorData() const + { return fCursorData; } - const uint8* CursorData() const - { return fCursorData; } +protected: + virtual void LastReferenceReleased(); - private: +private: friend class CursorManager; - BPoint fHotSpot; - team_id fOwningTeam; - vint32 fReferenceCount; - uint8* fCursorData; - CursorManager* fManager; + BPoint fHotSpot; + team_id fOwningTeam; + uint8* fCursorData; + CursorManager* fManager; }; class ServerCursorReference { public: - ServerCursorReference() - : fCursor(NULL) - { - } - ServerCursorReference(ServerCursor* cursor) - : fCursor(cursor) - { - if (fCursor) - fCursor->Acquire(); - } - ServerCursorReference(const ServerCursorReference& other) - : fCursor(other.fCursor) - { - if (fCursor) - fCursor->Acquire(); - } - virtual ~ServerCursorReference() - { - if (fCursor) - fCursor->Release(); - } + ServerCursorReference() + : + fCursor(NULL) + { + } - ServerCursorReference& operator=(const ServerCursorReference& other) - { - SetCursor(other.fCursor); - return *this; - } + ServerCursorReference(ServerCursor* cursor) + : + fCursor(cursor) + { + if (fCursor) + fCursor->AcquireReference(); + } + + ServerCursorReference(const ServerCursorReference& other) + : + fCursor(other.fCursor) + { + if (fCursor) + fCursor->AcquireReference(); + } + + virtual ~ServerCursorReference() + { + if (fCursor) + fCursor->ReleaseReference(); + } + + ServerCursorReference& operator=(const ServerCursorReference& other) + { + SetCursor(other.fCursor); + return *this; + } + + void SetCursor(ServerCursor* cursor) + { + if (fCursor == cursor) + return; + + if (cursor) + cursor->AcquireReference(); + + ServerCursor* oldCursor = fCursor; + + fCursor = cursor; + + if (oldCursor) + oldCursor->ReleaseReference(); + } + + ServerCursor* Cursor() const + { + return fCursor; + } - void SetCursor(ServerCursor* cursor) - { - if (fCursor == cursor) - return; - if (cursor) - cursor->Acquire(); - ServerCursor* oldCursor = fCursor; - fCursor = cursor; - if (oldCursor) - oldCursor->Release(); - } - ServerCursor* Cursor() const - { - return fCursor; - } private: ServerCursor* fCursor; }; diff --git a/src/servers/app/ServerWindow.cpp b/src/servers/app/ServerWindow.cpp index 8f43eda2ca..3f7edebe12 100644 --- a/src/servers/app/ServerWindow.cpp +++ b/src/servers/app/ServerWindow.cpp @@ -1820,7 +1820,7 @@ fDesktop->LockSingleWindow(); colorKey = bitmap->Overlay()->Color(); } - bitmap->Release(); + bitmap->ReleaseReference(); } else status = B_BAD_VALUE; } @@ -1999,7 +1999,7 @@ fDesktop->UnlockSingleWindow(); fDesktop->EventDispatcher().SetDragMessage(dragMessage, bitmap, offset); fDesktop->LockSingleWindow(); - bitmap->Release(); + bitmap->ReleaseReference(); } delete[] buffer; } @@ -2283,7 +2283,7 @@ ServerWindow::_DispatchViewDrawingMessage(int32 code, drawingEngine->DrawBitmap(bitmap, info.bitmapRect, info.viewRect, info.options); - bitmap->Release(); + bitmap->ReleaseReference(); } break; } @@ -3128,7 +3128,7 @@ ServerWindow::_DispatchPictureMessage(int32 code, BPrivate::LinkReceiver &link) bitmap->ColorSpace(), info.options, bitmap->Bits(), bitmap->BitsLength()); - bitmap->Release(); + bitmap->ReleaseReference(); break; } diff --git a/src/servers/app/View.cpp b/src/servers/app/View.cpp index 84c88887c8..2be4c66e48 100644 --- a/src/servers/app/View.cpp +++ b/src/servers/app/View.cpp @@ -127,7 +127,7 @@ View::View(IntRect frame, IntPoint scrollingOffset, const char* name, View::~View() { if (fViewBitmap != NULL) - gBitmapManager->DeleteBitmap(fViewBitmap); + fViewBitmap->ReleaseReference(); delete fScreenAndUserClipping; delete fUserClipping; @@ -137,7 +137,7 @@ View::~View() // fWindow->SetTopView(NULL); if (fCursor) - fCursor->Release(); + fCursor->ReleaseReference(); // iterate over children and delete each one View* view = fFirstChild; @@ -522,12 +522,12 @@ View::SetViewBitmap(ServerBitmap* bitmap, IntRect sourceRect, } else if (overlay != NULL) overlay->Hide(); - gBitmapManager->DeleteBitmap(fViewBitmap); + fViewBitmap->ReleaseReference(); } // the caller is allowed to delete the bitmap after setting the background if (bitmap != NULL) - bitmap->Acquire(); + bitmap->AcquireReference(); fViewBitmap = bitmap; fBitmapSource = sourceRect; @@ -1297,12 +1297,12 @@ View::SetCursor(ServerCursor* cursor) return; if (fCursor) - fCursor->Release(); + fCursor->ReleaseReference(); fCursor = cursor; if (fCursor) - fCursor->Acquire(); + fCursor->AcquireReference(); } diff --git a/src/servers/app/drawing/HWInterface.cpp b/src/servers/app/drawing/HWInterface.cpp index fe23d4f466..c9986090ec 100644 --- a/src/servers/app/drawing/HWInterface.cpp +++ b/src/servers/app/drawing/HWInterface.cpp @@ -152,12 +152,12 @@ HWInterface::SetCursor(ServerCursor* cursor) } if (fCursor) - fCursor->Release(); + fCursor->ReleaseReference(); fCursor = cursor; if (fCursor) - fCursor->Acquire(); + fCursor->AcquireReference(); Invalidate(oldFrame);