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