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:
+28
-20
@@ -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.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
#ifndef _CURSOR_H
|
#ifndef _CURSOR_H
|
||||||
@@ -11,31 +11,39 @@
|
|||||||
|
|
||||||
|
|
||||||
class BCursor : BArchivable {
|
class BCursor : BArchivable {
|
||||||
public:
|
public:
|
||||||
BCursor(const void* cursorData);
|
BCursor(const void* cursorData);
|
||||||
BCursor(BMessage* data);
|
BCursor(const BCursor& other);
|
||||||
virtual ~BCursor();
|
BCursor(BMessage* data);
|
||||||
|
virtual ~BCursor();
|
||||||
|
|
||||||
virtual status_t Archive(BMessage* archive, bool deep = true) const;
|
virtual status_t Archive(BMessage* archive,
|
||||||
static BArchivable* Instantiate(BMessage* archive);
|
bool deep = true) const;
|
||||||
|
static BArchivable* Instantiate(BMessage* archive);
|
||||||
|
|
||||||
private:
|
BCursor& operator=(const BCursor& other);
|
||||||
virtual status_t Perform(perform_code d, void* arg);
|
bool operator==(const BCursor& other) const;
|
||||||
|
bool operator!=(const BCursor& other) const;
|
||||||
|
|
||||||
virtual void _ReservedCursor1();
|
private:
|
||||||
virtual void _ReservedCursor2();
|
virtual status_t Perform(perform_code d, void* arg);
|
||||||
virtual void _ReservedCursor3();
|
|
||||||
virtual void _ReservedCursor4();
|
|
||||||
|
|
||||||
private:
|
virtual void _ReservedCursor1();
|
||||||
friend class BApplication;
|
virtual void _ReservedCursor2();
|
||||||
friend class BView;
|
virtual void _ReservedCursor3();
|
||||||
|
virtual void _ReservedCursor4();
|
||||||
|
|
||||||
int32 fServerToken;
|
void _FreeCursorData();
|
||||||
bool fNeedToFree;
|
|
||||||
mutable bool fPendingViewCursor;
|
|
||||||
|
|
||||||
uint32 _reserved[6];
|
private:
|
||||||
|
friend class BApplication;
|
||||||
|
friend class BView;
|
||||||
|
|
||||||
|
int32 fServerToken;
|
||||||
|
bool fNeedToFree;
|
||||||
|
mutable bool fPendingViewCursor;
|
||||||
|
|
||||||
|
uint32 _reserved[6];
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // _CURSOR_H
|
#endif // _CURSOR_H
|
||||||
|
|||||||
@@ -68,6 +68,7 @@ enum {
|
|||||||
AS_QUERY_CURSOR_HIDDEN,
|
AS_QUERY_CURSOR_HIDDEN,
|
||||||
|
|
||||||
AS_CREATE_CURSOR,
|
AS_CREATE_CURSOR,
|
||||||
|
AS_REFERENCE_CURSOR,
|
||||||
AS_DELETE_CURSOR,
|
AS_DELETE_CURSOR,
|
||||||
|
|
||||||
AS_BEGIN_RECT_TRACKING,
|
AS_BEGIN_RECT_TRACKING,
|
||||||
|
|||||||
+62
-8
@@ -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)
|
BCursor::BCursor(BMessage *data)
|
||||||
{
|
{
|
||||||
// undefined on BeOS
|
// undefined on BeOS
|
||||||
@@ -74,14 +84,7 @@ BCursor::BCursor(BMessage *data)
|
|||||||
|
|
||||||
BCursor::~BCursor()
|
BCursor::~BCursor()
|
||||||
{
|
{
|
||||||
// Notify server to deallocate server-side objects for this cursor
|
_FreeCursorData();
|
||||||
if (fNeedToFree) {
|
|
||||||
BPrivate::AppServerLink link;
|
|
||||||
link.StartMessage(AS_DELETE_CURSOR);
|
|
||||||
link.Attach<int32>(fServerToken);
|
|
||||||
link.Attach<bool>(fPendingViewCursor);
|
|
||||||
link.Flush();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -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
|
status_t
|
||||||
BCursor::Perform(perform_code d, void *arg)
|
BCursor::Perform(perform_code d, void *arg)
|
||||||
{
|
{
|
||||||
@@ -112,3 +151,18 @@ void BCursor::_ReservedCursor1() {}
|
|||||||
void BCursor::_ReservedCursor2() {}
|
void BCursor::_ReservedCursor2() {}
|
||||||
void BCursor::_ReservedCursor3() {}
|
void BCursor::_ReservedCursor3() {}
|
||||||
void BCursor::_ReservedCursor4() {}
|
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) {
|
if (link.Read(cursorData, sizeof(cursorData)) >= B_OK) {
|
||||||
cursor = fDesktop->GetCursorManager().CreateCursor(fClientTeam,
|
cursor = fDesktop->GetCursorManager().CreateCursor(fClientTeam,
|
||||||
cursorData);
|
cursorData);
|
||||||
if (cursor == NULL)
|
if (cursor == NULL)
|
||||||
status = B_NO_MEMORY;
|
status = B_NO_MEMORY;
|
||||||
}
|
}
|
||||||
@@ -954,6 +954,27 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
|||||||
fLink.Flush();
|
fLink.Flush();
|
||||||
break;
|
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:
|
case AS_DELETE_CURSOR:
|
||||||
{
|
{
|
||||||
STRACE(("ServerApp %s: Delete BCursor\n", Signature()));
|
STRACE(("ServerApp %s: Delete BCursor\n", Signature()));
|
||||||
@@ -968,8 +989,9 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
|||||||
if (!fDesktop->GetCursorManager().Lock())
|
if (!fDesktop->GetCursorManager().Lock())
|
||||||
break;
|
break;
|
||||||
|
|
||||||
ServerCursor* cursor = fDesktop->GetCursorManager().FindCursor(token);
|
ServerCursor* cursor
|
||||||
if (cursor) {
|
= fDesktop->GetCursorManager().FindCursor(token);
|
||||||
|
if (cursor != NULL) {
|
||||||
if (pendingViewCursor)
|
if (pendingViewCursor)
|
||||||
cursor->SetPendingViewCursor(true);
|
cursor->SetPendingViewCursor(true);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user