* Cursors are now reference counted, so it shouldn't be possible anymore
to delete them accidently :) * You should no longer call HWInterface::SetCursor(), but the new Desktop::SetCursor() if you need to change the cursor. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@16238 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -46,11 +46,16 @@ class ServerCursor : public ServerBitmap {
|
||||
|
||||
int32 Token() const
|
||||
{ return fToken; }
|
||||
|
||||
void Acquire() { atomic_add(&fReferenceCount, 1); }
|
||||
bool Release() { return atomic_add(&fReferenceCount, -1) == 1; }
|
||||
|
||||
private:
|
||||
friend class CursorManager;
|
||||
|
||||
|
||||
BPoint fHotSpot;
|
||||
team_id fOwningTeam;
|
||||
int32 fReferenceCount;
|
||||
};
|
||||
|
||||
#endif // SERVER_CURSOR_H
|
||||
|
||||
@@ -98,6 +98,14 @@ CursorManager::AddCursor(ServerCursor* cursor, int32 token)
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CursorManager::_RemoveCursor(ServerCursor* cursor)
|
||||
{
|
||||
fCursorList.RemoveItem(cursor);
|
||||
fTokenSpace.RemoveToken(cursor->fToken);
|
||||
}
|
||||
|
||||
|
||||
ServerCursor*
|
||||
CursorManager::_RemoveCursor(int32 index)
|
||||
{
|
||||
@@ -110,24 +118,20 @@ CursorManager::_RemoveCursor(int32 index)
|
||||
|
||||
|
||||
/*!
|
||||
\brief Removes a cursor from the internal list and deletes it
|
||||
\param token Token of the cursor to be deleted
|
||||
|
||||
If the cursor is not found, this call does nothing
|
||||
\brief Releases a reference to a cursor
|
||||
|
||||
If this was the last reference to this cursor, it will be deleted.
|
||||
*/
|
||||
void
|
||||
CursorManager::DeleteCursor(int32 token)
|
||||
CursorManager::ReleaseCursor(ServerCursor* cursor)
|
||||
{
|
||||
Lock();
|
||||
|
||||
for (int32 index = 0; index < fCursorList.CountItems(); index++) {
|
||||
ServerCursor *cursor = (ServerCursor *)fCursorList.ItemAt(index);
|
||||
|
||||
if (cursor && cursor->fToken == token) {
|
||||
_RemoveCursor(index);
|
||||
delete cursor;
|
||||
break;
|
||||
}
|
||||
if (cursor->Release()) {
|
||||
// this was the last reference, remove the cursor
|
||||
|
||||
_RemoveCursor(cursor);
|
||||
delete cursor;
|
||||
}
|
||||
|
||||
Unlock();
|
||||
|
||||
@@ -34,9 +34,10 @@ class CursorManager : public BLocker {
|
||||
virtual ~CursorManager();
|
||||
|
||||
int32 AddCursor(ServerCursor* cursor, int32 token = -1);
|
||||
void DeleteCursor(int32 token);
|
||||
void DeleteCursors(team_id team);
|
||||
|
||||
void ReleaseCursor(ServerCursor* cursor);
|
||||
|
||||
void SetCursorSet(const char* path);
|
||||
ServerCursor* GetCursor(cursor_which which);
|
||||
cursor_which GetCursorWhich();
|
||||
@@ -45,6 +46,7 @@ class CursorManager : public BLocker {
|
||||
ServerCursor* FindCursor(int32 token);
|
||||
|
||||
private:
|
||||
void _RemoveCursor(ServerCursor* cursor);
|
||||
ServerCursor* _RemoveCursor(int32 index);
|
||||
|
||||
BList fCursorList;
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include "InputManager.h"
|
||||
#include "ServerApp.h"
|
||||
#include "ServerConfig.h"
|
||||
#include "ServerCursor.h"
|
||||
#include "ServerScreen.h"
|
||||
#include "ServerWindow.h"
|
||||
#include "WindowPrivate.h"
|
||||
@@ -316,10 +317,8 @@ Desktop::Init()
|
||||
fEventDispatcher.SetMouseFilter(new MouseFilter(this));
|
||||
fEventDispatcher.SetKeyboardFilter(new KeyboardFilter(this));
|
||||
|
||||
// take care of setting the default cursor
|
||||
ServerCursor *cursor = fCursorManager.GetCursor(B_CURSOR_DEFAULT);
|
||||
if (cursor)
|
||||
fVirtualScreen.HWInterface()->SetCursor(cursor);
|
||||
SetCursor(NULL);
|
||||
// this will set the default cursor
|
||||
|
||||
fVirtualScreen.HWInterface()->MoveCursorTo(fVirtualScreen.Frame().Width() / 2,
|
||||
fVirtualScreen.Frame().Height() / 2);
|
||||
@@ -564,6 +563,31 @@ Desktop::BroadcastToAllApps(int32 code)
|
||||
}
|
||||
|
||||
|
||||
ServerCursor*
|
||||
Desktop::Cursor() const
|
||||
{
|
||||
return HWInterface()->Cursor();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Desktop::SetCursor(ServerCursor* newCursor)
|
||||
{
|
||||
if (newCursor == NULL)
|
||||
newCursor = fCursorManager.GetCursor(B_CURSOR_DEFAULT);
|
||||
|
||||
ServerCursor* oldCursor = Cursor();
|
||||
if (newCursor == oldCursor)
|
||||
return;
|
||||
|
||||
newCursor->Acquire();
|
||||
HWInterface()->SetCursor(newCursor);
|
||||
|
||||
if (oldCursor != NULL)
|
||||
fCursorManager.ReleaseCursor(oldCursor);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Desktop::UpdateWorkspaces()
|
||||
{
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2001-2005, Haiku.
|
||||
* Copyright 2001-2006, Haiku.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
@@ -73,6 +73,9 @@ class Desktop : public MessageLooper, public ScreenOwner {
|
||||
|
||||
CursorManager& GetCursorManager() { return fCursorManager; }
|
||||
|
||||
void SetCursor(ServerCursor* cursor);
|
||||
ServerCursor* Cursor() const;
|
||||
|
||||
void ScreenChanged(Screen* screen);
|
||||
|
||||
void ScreenRemoved(Screen* screen) {}
|
||||
|
||||
@@ -290,9 +290,7 @@ ServerApp::Activate(bool value)
|
||||
void
|
||||
ServerApp::SetCursor()
|
||||
{
|
||||
if (fAppCursor != NULL)
|
||||
fDesktop->HWInterface()->SetCursor(fAppCursor);
|
||||
|
||||
fDesktop->SetCursor(fAppCursor);
|
||||
fDesktop->HWInterface()->SetCursorVisible(fCursorHideLevel == 0);
|
||||
}
|
||||
|
||||
@@ -946,7 +944,8 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
||||
if (fAppCursor && fAppCursor->Token() == token)
|
||||
fAppCursor = NULL;
|
||||
|
||||
fDesktop->GetCursorManager().DeleteCursor(token);
|
||||
if (ServerCursor* cursor = fDesktop->GetCursorManager().FindCursor(token))
|
||||
fDesktop->GetCursorManager().ReleaseCursor(cursor);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,8 @@ ServerCursor::ServerCursor(BRect r, color_space format,
|
||||
screen_id screen)
|
||||
: ServerBitmap(r, format, flags, bytesPerRow, screen),
|
||||
fHotSpot(hotspot),
|
||||
fOwningTeam(-1)
|
||||
fOwningTeam(-1),
|
||||
fReferenceCount(1)
|
||||
{
|
||||
fHotSpot.ConstrainTo(Bounds());
|
||||
_AllocateBuffer();
|
||||
@@ -49,7 +50,8 @@ ServerCursor::ServerCursor(BRect r, color_space format,
|
||||
ServerCursor::ServerCursor(const int8* data)
|
||||
: ServerBitmap(BRect(0, 0, 15, 15), B_RGBA32, 0),
|
||||
fHotSpot(0, 0),
|
||||
fOwningTeam(-1)
|
||||
fOwningTeam(-1),
|
||||
fReferenceCount(1)
|
||||
{
|
||||
// 68-byte array used in R5 for holding cursors.
|
||||
// This API has serious problems and should be deprecated(but supported) in R2
|
||||
@@ -116,7 +118,8 @@ ServerCursor::ServerCursor(const uint8* alreadyPaddedData,
|
||||
color_space format)
|
||||
: ServerBitmap(BRect(0, 0, width - 1, height - 1), format, 0),
|
||||
fHotSpot(0, 0),
|
||||
fOwningTeam(-1)
|
||||
fOwningTeam(-1),
|
||||
fReferenceCount(1)
|
||||
{
|
||||
_AllocateBuffer();
|
||||
if (Bits())
|
||||
@@ -131,7 +134,8 @@ ServerCursor::ServerCursor(const uint8* alreadyPaddedData,
|
||||
ServerCursor::ServerCursor(const ServerCursor* cursor)
|
||||
: ServerBitmap(cursor),
|
||||
fHotSpot(0, 0),
|
||||
fOwningTeam(-1)
|
||||
fOwningTeam(-1),
|
||||
fReferenceCount(1)
|
||||
{
|
||||
// TODO: Hm. I don't move this into the if clause,
|
||||
// because it might break code elsewhere.
|
||||
@@ -158,9 +162,9 @@ ServerCursor::~ServerCursor()
|
||||
\param pt New location of hotspot, constrained to the cursor's boundaries.
|
||||
*/
|
||||
void
|
||||
ServerCursor::SetHotSpot(BPoint pt)
|
||||
ServerCursor::SetHotSpot(BPoint hotSpot)
|
||||
{
|
||||
fHotSpot = pt;
|
||||
fHotSpot = hotSpot;
|
||||
fHotSpot.ConstrainTo(Bounds());
|
||||
}
|
||||
|
||||
|
||||
@@ -986,17 +986,12 @@ WindowLayer::MouseMoved(BMessage *msg, BPoint where, int32* _viewToken,
|
||||
if (IsFocus()) {
|
||||
// TODO: there is more for real cursor support, ie. if a window is closed,
|
||||
// new app cursor shouldn't override view cursor, ...
|
||||
ServerCursor* currentCursor = fDesktop->HWInterface()->Cursor();
|
||||
ServerCursor* cursor = ServerWindow()->App()->Cursor();
|
||||
|
||||
if (view != NULL && view->Cursor() != NULL)
|
||||
cursor = view->Cursor();
|
||||
|
||||
if (cursor == NULL)
|
||||
cursor = fDesktop->GetCursorManager().GetCursor(B_CURSOR_DEFAULT);
|
||||
|
||||
if (cursor != currentCursor && cursor != NULL)
|
||||
fDesktop->HWInterface()->SetCursor(cursor);
|
||||
fDesktop->SetCursor(cursor);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user