Make it possible to properly use operator= on BCursors by making sure the
reference counting is maintained correctly in the app_server. While reviewing this code, I have my doubts that my previous solution for handling pending SetViewCursor() calls is always working as it is intended. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31131 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
76d87570c9
commit
5d62f8e0e5
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2006, Haiku, Inc. All Rights Reserved.
|
||||
* Copyright 2006-2009, Haiku, Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*/
|
||||
#ifndef _CURSOR_H
|
||||
@ -11,31 +11,39 @@
|
||||
|
||||
|
||||
class BCursor : BArchivable {
|
||||
public:
|
||||
BCursor(const void* cursorData);
|
||||
BCursor(BMessage* data);
|
||||
virtual ~BCursor();
|
||||
public:
|
||||
BCursor(const void* cursorData);
|
||||
BCursor(const BCursor& other);
|
||||
BCursor(BMessage* data);
|
||||
virtual ~BCursor();
|
||||
|
||||
virtual status_t Archive(BMessage* archive, bool deep = true) const;
|
||||
static BArchivable* Instantiate(BMessage* archive);
|
||||
virtual status_t Archive(BMessage* archive,
|
||||
bool deep = true) const;
|
||||
static BArchivable* Instantiate(BMessage* archive);
|
||||
|
||||
private:
|
||||
virtual status_t Perform(perform_code d, void* arg);
|
||||
BCursor& operator=(const BCursor& other);
|
||||
bool operator==(const BCursor& other) const;
|
||||
bool operator!=(const BCursor& other) const;
|
||||
|
||||
virtual void _ReservedCursor1();
|
||||
virtual void _ReservedCursor2();
|
||||
virtual void _ReservedCursor3();
|
||||
virtual void _ReservedCursor4();
|
||||
private:
|
||||
virtual status_t Perform(perform_code d, void* arg);
|
||||
|
||||
private:
|
||||
friend class BApplication;
|
||||
friend class BView;
|
||||
virtual void _ReservedCursor1();
|
||||
virtual void _ReservedCursor2();
|
||||
virtual void _ReservedCursor3();
|
||||
virtual void _ReservedCursor4();
|
||||
|
||||
int32 fServerToken;
|
||||
bool fNeedToFree;
|
||||
mutable bool fPendingViewCursor;
|
||||
void _FreeCursorData();
|
||||
|
||||
uint32 _reserved[6];
|
||||
private:
|
||||
friend class BApplication;
|
||||
friend class BView;
|
||||
|
||||
int32 fServerToken;
|
||||
bool fNeedToFree;
|
||||
mutable bool fPendingViewCursor;
|
||||
|
||||
uint32 _reserved[6];
|
||||
};
|
||||
|
||||
#endif // _CURSOR_H
|
||||
|
@ -68,6 +68,7 @@ enum {
|
||||
AS_QUERY_CURSOR_HIDDEN,
|
||||
|
||||
AS_CREATE_CURSOR,
|
||||
AS_REFERENCE_CURSOR,
|
||||
AS_DELETE_CURSOR,
|
||||
|
||||
AS_BEGIN_RECT_TRACKING,
|
||||
|
@ -63,6 +63,16 @@ BCursor::BCursor(const void *cursorData)
|
||||
}
|
||||
|
||||
|
||||
BCursor::BCursor(const BCursor& other)
|
||||
:
|
||||
fServerToken(-1),
|
||||
fNeedToFree(false),
|
||||
fPendingViewCursor(false)
|
||||
{
|
||||
*this = other;
|
||||
}
|
||||
|
||||
|
||||
BCursor::BCursor(BMessage *data)
|
||||
{
|
||||
// undefined on BeOS
|
||||
@ -74,14 +84,7 @@ BCursor::BCursor(BMessage *data)
|
||||
|
||||
BCursor::~BCursor()
|
||||
{
|
||||
// Notify server to deallocate server-side objects for this cursor
|
||||
if (fNeedToFree) {
|
||||
BPrivate::AppServerLink link;
|
||||
link.StartMessage(AS_DELETE_CURSOR);
|
||||
link.Attach<int32>(fServerToken);
|
||||
link.Attach<bool>(fPendingViewCursor);
|
||||
link.Flush();
|
||||
}
|
||||
_FreeCursorData();
|
||||
}
|
||||
|
||||
|
||||
@ -101,6 +104,42 @@ BCursor::Instantiate(BMessage *data)
|
||||
}
|
||||
|
||||
|
||||
BCursor&
|
||||
BCursor::operator=(const BCursor& other)
|
||||
{
|
||||
if (&other != this && other != *this) {
|
||||
_FreeCursorData();
|
||||
|
||||
fServerToken = other.fServerToken;
|
||||
fNeedToFree = other.fNeedToFree;
|
||||
fPendingViewCursor = false;
|
||||
|
||||
if (fNeedToFree) {
|
||||
// Tell app_server that there is another reference for this
|
||||
// cursor data!
|
||||
BPrivate::AppServerLink link;
|
||||
link.StartMessage(AS_REFERENCE_CURSOR);
|
||||
link.Attach<int32>(fServerToken);
|
||||
}
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
BCursor::operator==(const BCursor& other) const
|
||||
{
|
||||
return fServerToken == other.fServerToken;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
BCursor::operator!=(const BCursor& other) const
|
||||
{
|
||||
return fServerToken != other.fServerToken;
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BCursor::Perform(perform_code d, void *arg)
|
||||
{
|
||||
@ -112,3 +151,18 @@ void BCursor::_ReservedCursor1() {}
|
||||
void BCursor::_ReservedCursor2() {}
|
||||
void BCursor::_ReservedCursor3() {}
|
||||
void BCursor::_ReservedCursor4() {}
|
||||
|
||||
|
||||
void
|
||||
BCursor::_FreeCursorData()
|
||||
{
|
||||
// Notify server to deallocate server-side objects for this cursor
|
||||
if (fNeedToFree) {
|
||||
BPrivate::AppServerLink link;
|
||||
link.StartMessage(AS_DELETE_CURSOR);
|
||||
link.Attach<int32>(fServerToken);
|
||||
link.Attach<bool>(fPendingViewCursor);
|
||||
link.Flush();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -939,7 +939,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
||||
|
||||
if (link.Read(cursorData, sizeof(cursorData)) >= B_OK) {
|
||||
cursor = fDesktop->GetCursorManager().CreateCursor(fClientTeam,
|
||||
cursorData);
|
||||
cursorData);
|
||||
if (cursor == NULL)
|
||||
status = B_NO_MEMORY;
|
||||
}
|
||||
@ -954,6 +954,27 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
||||
fLink.Flush();
|
||||
break;
|
||||
}
|
||||
case AS_REFERENCE_CURSOR:
|
||||
{
|
||||
STRACE(("ServerApp %s: Reference BCursor\n", Signature()));
|
||||
// Attached data:
|
||||
// 1) int32 token ID of the cursor to reference
|
||||
int32 token;
|
||||
if (link.Read<int32>(&token) != B_OK)
|
||||
break;
|
||||
|
||||
if (!fDesktop->GetCursorManager().Lock())
|
||||
break;
|
||||
|
||||
ServerCursor* cursor
|
||||
= fDesktop->GetCursorManager().FindCursor(token);
|
||||
if (cursor != NULL)
|
||||
cursor->Acquire();
|
||||
|
||||
fDesktop->GetCursorManager().Unlock();
|
||||
|
||||
break;
|
||||
}
|
||||
case AS_DELETE_CURSOR:
|
||||
{
|
||||
STRACE(("ServerApp %s: Delete BCursor\n", Signature()));
|
||||
@ -968,8 +989,9 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
||||
if (!fDesktop->GetCursorManager().Lock())
|
||||
break;
|
||||
|
||||
ServerCursor* cursor = fDesktop->GetCursorManager().FindCursor(token);
|
||||
if (cursor) {
|
||||
ServerCursor* cursor
|
||||
= fDesktop->GetCursorManager().FindCursor(token);
|
||||
if (cursor != NULL) {
|
||||
if (pendingViewCursor)
|
||||
cursor->SetPendingViewCursor(true);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user