* Moved the implementation of SetViewCursor from the thread of the
window of the view into the application thread. This solves the race condition with asynchronous SetViewCursor and deleting the cursor immediately afterwards for real. * The ServerApp now requires a reference to the current cursor, just in case... * Added TODOs for caching the BView token, it's currently resolved for every single BView call that talks to the server... not good! git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@31133 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
dee5a4f49f
commit
19e179ca4f
@ -41,8 +41,9 @@ private:
|
|||||||
|
|
||||||
int32 fServerToken;
|
int32 fServerToken;
|
||||||
bool fNeedToFree;
|
bool fNeedToFree;
|
||||||
mutable bool fPendingViewCursor;
|
|
||||||
|
|
||||||
|
bool _reservedWasPendingViewCursor;
|
||||||
|
// Probably bogus because of padding.
|
||||||
uint32 _reserved[6];
|
uint32 _reserved[6];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -61,6 +61,7 @@ enum {
|
|||||||
|
|
||||||
// Cursor commands
|
// Cursor commands
|
||||||
AS_SET_CURSOR,
|
AS_SET_CURSOR,
|
||||||
|
AS_SET_VIEW_CURSOR,
|
||||||
|
|
||||||
AS_SHOW_CURSOR,
|
AS_SHOW_CURSOR,
|
||||||
AS_HIDE_CURSOR,
|
AS_HIDE_CURSOR,
|
||||||
@ -258,7 +259,6 @@ enum {
|
|||||||
AS_VIEW_SET_ORIGIN,
|
AS_VIEW_SET_ORIGIN,
|
||||||
AS_VIEW_GET_ORIGIN,
|
AS_VIEW_GET_ORIGIN,
|
||||||
AS_VIEW_RESIZE_MODE,
|
AS_VIEW_RESIZE_MODE,
|
||||||
AS_VIEW_SET_CURSOR,
|
|
||||||
AS_VIEW_BEGIN_RECT_TRACK,
|
AS_VIEW_BEGIN_RECT_TRACK,
|
||||||
AS_VIEW_END_RECT_TRACK,
|
AS_VIEW_END_RECT_TRACK,
|
||||||
AS_VIEW_DRAG_RECT,
|
AS_VIEW_DRAG_RECT,
|
||||||
|
@ -55,6 +55,7 @@ struct ViewDragImageInfo {
|
|||||||
|
|
||||||
struct ViewSetViewCursorInfo {
|
struct ViewSetViewCursorInfo {
|
||||||
int32 cursorToken;
|
int32 cursorToken;
|
||||||
|
int32 viewToken;
|
||||||
bool sync;
|
bool sync;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -30,8 +30,7 @@ const BCursor *B_CURSOR_I_BEAM;
|
|||||||
BCursor::BCursor(const void *cursorData)
|
BCursor::BCursor(const void *cursorData)
|
||||||
:
|
:
|
||||||
fServerToken(-1),
|
fServerToken(-1),
|
||||||
fNeedToFree(false),
|
fNeedToFree(false)
|
||||||
fPendingViewCursor(false)
|
|
||||||
{
|
{
|
||||||
const uint8 *data = (const uint8 *)cursorData;
|
const uint8 *data = (const uint8 *)cursorData;
|
||||||
|
|
||||||
@ -66,8 +65,7 @@ BCursor::BCursor(const void *cursorData)
|
|||||||
BCursor::BCursor(const BCursor& other)
|
BCursor::BCursor(const BCursor& other)
|
||||||
:
|
:
|
||||||
fServerToken(-1),
|
fServerToken(-1),
|
||||||
fNeedToFree(false),
|
fNeedToFree(false)
|
||||||
fPendingViewCursor(false)
|
|
||||||
{
|
{
|
||||||
*this = other;
|
*this = other;
|
||||||
}
|
}
|
||||||
@ -78,7 +76,6 @@ BCursor::BCursor(BMessage *data)
|
|||||||
// undefined on BeOS
|
// undefined on BeOS
|
||||||
fServerToken = -1;
|
fServerToken = -1;
|
||||||
fNeedToFree = false;
|
fNeedToFree = false;
|
||||||
fPendingViewCursor = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -112,7 +109,6 @@ BCursor::operator=(const BCursor& other)
|
|||||||
|
|
||||||
fServerToken = other.fServerToken;
|
fServerToken = other.fServerToken;
|
||||||
fNeedToFree = other.fNeedToFree;
|
fNeedToFree = other.fNeedToFree;
|
||||||
fPendingViewCursor = false;
|
|
||||||
|
|
||||||
if (fNeedToFree) {
|
if (fNeedToFree) {
|
||||||
// Tell app_server that there is another reference for this
|
// Tell app_server that there is another reference for this
|
||||||
@ -161,7 +157,6 @@ BCursor::_FreeCursorData()
|
|||||||
BPrivate::AppServerLink link;
|
BPrivate::AppServerLink link;
|
||||||
link.StartMessage(AS_DELETE_CURSOR);
|
link.StartMessage(AS_DELETE_CURSOR);
|
||||||
link.Attach<int32>(fServerToken);
|
link.Attach<int32>(fServerToken);
|
||||||
link.Attach<bool>(fPendingViewCursor);
|
|
||||||
link.Flush();
|
link.Flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -996,26 +996,21 @@ BView::SetViewCursor(const BCursor *cursor, bool sync)
|
|||||||
if (cursor == NULL || fOwner == NULL)
|
if (cursor == NULL || fOwner == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_CheckLockAndSwitchCurrent();
|
_CheckLock();
|
||||||
|
|
||||||
fOwner->fLink->StartMessage(AS_VIEW_SET_CURSOR);
|
|
||||||
ViewSetViewCursorInfo info;
|
ViewSetViewCursorInfo info;
|
||||||
info.cursorToken = cursor->fServerToken;
|
info.cursorToken = cursor->fServerToken;
|
||||||
|
info.viewToken = _get_object_token_(this); // TODO: Use server_token!
|
||||||
info.sync = sync;
|
info.sync = sync;
|
||||||
fOwner->fLink->Attach<ViewSetViewCursorInfo>(info);
|
|
||||||
|
|
||||||
if (!sync) {
|
BPrivate::AppServerLink link;
|
||||||
cursor->fPendingViewCursor = true;
|
link.StartMessage(AS_SET_VIEW_CURSOR);
|
||||||
// this avoids a race condition in case the cursor is
|
link.Attach<ViewSetViewCursorInfo>(info);
|
||||||
// immediately deleted after this call, as the deletion
|
|
||||||
// is handled by the application, not the window
|
if (sync) {
|
||||||
} else {
|
// Make sure the server has processed the message.
|
||||||
// make sure the server has processed the
|
|
||||||
// message and "acquired" the cursor in
|
|
||||||
// the window thread before returning from
|
|
||||||
// this function
|
|
||||||
int32 code;
|
int32 code;
|
||||||
fOwner->fLink->FlushWithReply(code);
|
link.FlushWithReply(code);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3911,6 +3906,7 @@ BView::_RemoveSelf()
|
|||||||
if (owner != NULL && !fTopLevelView) {
|
if (owner != NULL && !fTopLevelView) {
|
||||||
// the top level view is deleted by the app_server automatically
|
// the top level view is deleted by the app_server automatically
|
||||||
owner->fLink->StartMessage(AS_VIEW_DELETE);
|
owner->fLink->StartMessage(AS_VIEW_DELETE);
|
||||||
|
// TODO: Use server_token
|
||||||
owner->fLink->Attach<int32>(_get_object_token_(this));
|
owner->fLink->Attach<int32>(_get_object_token_(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4250,7 +4246,7 @@ BView::MessageReceived(BMessage* msg)
|
|||||||
if (err == B_OK) {
|
if (err == B_OK) {
|
||||||
if (newHiddenState == true)
|
if (newHiddenState == true)
|
||||||
Hide();
|
Hide();
|
||||||
else
|
else
|
||||||
Show();
|
Show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4906,6 +4902,7 @@ BView::_CreateSelf()
|
|||||||
else
|
else
|
||||||
fOwner->fLink->StartMessage(AS_VIEW_CREATE);
|
fOwner->fLink->StartMessage(AS_VIEW_CREATE);
|
||||||
|
|
||||||
|
// TODO: Use server_token
|
||||||
fOwner->fLink->Attach<int32>(_get_object_token_(this));
|
fOwner->fLink->Attach<int32>(_get_object_token_(this));
|
||||||
fOwner->fLink->AttachString(Name());
|
fOwner->fLink->AttachString(Name());
|
||||||
fOwner->fLink->Attach<BRect>(Frame());
|
fOwner->fLink->Attach<BRect>(Frame());
|
||||||
@ -4919,6 +4916,7 @@ BView::_CreateSelf()
|
|||||||
if (fTopLevelView)
|
if (fTopLevelView)
|
||||||
fOwner->fLink->Attach<int32>(B_NULL_TOKEN);
|
fOwner->fLink->Attach<int32>(B_NULL_TOKEN);
|
||||||
else
|
else
|
||||||
|
// TODO: Use server_token
|
||||||
fOwner->fLink->Attach<int32>(_get_object_token_(fParent));
|
fOwner->fLink->Attach<int32>(_get_object_token_(fParent));
|
||||||
fOwner->fLink->Flush();
|
fOwner->fLink->Flush();
|
||||||
|
|
||||||
@ -5127,6 +5125,7 @@ BView::_Detach()
|
|||||||
if (fOwner->fLastMouseMovedView == this)
|
if (fOwner->fLastMouseMovedView == this)
|
||||||
fOwner->fLastMouseMovedView = NULL;
|
fOwner->fLastMouseMovedView = NULL;
|
||||||
|
|
||||||
|
// TODO: Use server_token
|
||||||
if (fOwner->fLastViewToken == _get_object_token_(this))
|
if (fOwner->fLastViewToken == _get_object_token_(this))
|
||||||
fOwner->fLastViewToken = B_NULL_TOKEN;
|
fOwner->fLastViewToken = B_NULL_TOKEN;
|
||||||
|
|
||||||
@ -5344,6 +5343,7 @@ BView::_CheckLock() const
|
|||||||
void
|
void
|
||||||
BView::_SwitchServerCurrentView() const
|
BView::_SwitchServerCurrentView() const
|
||||||
{
|
{
|
||||||
|
// TODO: Use server_token
|
||||||
int32 serverToken = _get_object_token_(this);
|
int32 serverToken = _get_object_token_(this);
|
||||||
|
|
||||||
if (fOwner->fLastViewToken != serverToken) {
|
if (fOwner->fLastViewToken != serverToken) {
|
||||||
|
@ -45,6 +45,7 @@ string_for_message_code(uint32 code, BString& string)
|
|||||||
|
|
||||||
// Cursor commands
|
// Cursor commands
|
||||||
case AS_SET_CURSOR: string = "AS_SET_CURSOR"; break;
|
case AS_SET_CURSOR: string = "AS_SET_CURSOR"; break;
|
||||||
|
case AS_SET_VIEW_CURSOR: string = "AS_SET_VIEW_CURSOR"; break;
|
||||||
|
|
||||||
case AS_SHOW_CURSOR: string = "AS_SHOW_CURSOR"; break;
|
case AS_SHOW_CURSOR: string = "AS_SHOW_CURSOR"; break;
|
||||||
case AS_HIDE_CURSOR: string = "AS_HIDE_CURSOR"; break;
|
case AS_HIDE_CURSOR: string = "AS_HIDE_CURSOR"; break;
|
||||||
@ -52,6 +53,7 @@ string_for_message_code(uint32 code, BString& string)
|
|||||||
case AS_QUERY_CURSOR_HIDDEN: string = "AS_QUERY_CURSOR_HIDDEN"; break;
|
case AS_QUERY_CURSOR_HIDDEN: string = "AS_QUERY_CURSOR_HIDDEN"; break;
|
||||||
|
|
||||||
case AS_CREATE_CURSOR: string = "AS_CREATE_CURSOR"; break;
|
case AS_CREATE_CURSOR: string = "AS_CREATE_CURSOR"; break;
|
||||||
|
case AS_REFERENCE_CURSOR: string = "AS_REFERENCE_CURSOR"; break;
|
||||||
case AS_DELETE_CURSOR: string = "AS_DELETE_CURSOR"; break;
|
case AS_DELETE_CURSOR: string = "AS_DELETE_CURSOR"; break;
|
||||||
|
|
||||||
case AS_BEGIN_RECT_TRACKING: string = "AS_BEGIN_RECT_TRACKING"; break;
|
case AS_BEGIN_RECT_TRACKING: string = "AS_BEGIN_RECT_TRACKING"; break;
|
||||||
@ -64,7 +66,7 @@ string_for_message_code(uint32 code, BString& string)
|
|||||||
case AS_QUIT_WINDOW: string = "AS_QUIT_WINDOW"; break;
|
case AS_QUIT_WINDOW: string = "AS_QUIT_WINDOW"; break;
|
||||||
case AS_SEND_BEHIND: string = "AS_SEND_BEHIND"; break;
|
case AS_SEND_BEHIND: string = "AS_SEND_BEHIND"; break;
|
||||||
case AS_SET_LOOK: string = "AS_SET_LOOK"; break;
|
case AS_SET_LOOK: string = "AS_SET_LOOK"; break;
|
||||||
case AS_SET_FEEL: string = "AS_SET_FEEL"; break;
|
case AS_SET_FEEL: string = "AS_SET_FEEL"; break;
|
||||||
case AS_SET_FLAGS: string = "AS_SET_FLAGS"; break;
|
case AS_SET_FLAGS: string = "AS_SET_FLAGS"; break;
|
||||||
case AS_DISABLE_UPDATES: string = "AS_DISABLE_UPDATES"; break;
|
case AS_DISABLE_UPDATES: string = "AS_DISABLE_UPDATES"; break;
|
||||||
case AS_ENABLE_UPDATES: string = "AS_ENABLE_UPDATES"; break;
|
case AS_ENABLE_UPDATES: string = "AS_ENABLE_UPDATES"; break;
|
||||||
@ -140,7 +142,7 @@ string_for_message_code(uint32 code, BString& string)
|
|||||||
case AS_GET_ACCELERANT_INFO: string = "AS_GET_ACCELERANT_INFO"; break;
|
case AS_GET_ACCELERANT_INFO: string = "AS_GET_ACCELERANT_INFO"; break;
|
||||||
case AS_GET_MONITOR_INFO: string = "AS_GET_MONITOR_INFO"; break;
|
case AS_GET_MONITOR_INFO: string = "AS_GET_MONITOR_INFO"; break;
|
||||||
case AS_GET_FRAME_BUFFER_CONFIG: string = "AS_GET_FRAME_BUFFER_CONFIG"; break;
|
case AS_GET_FRAME_BUFFER_CONFIG: string = "AS_GET_FRAME_BUFFER_CONFIG"; break;
|
||||||
|
|
||||||
case AS_SET_DPMS: string = "AS_SET_DPMS"; break;
|
case AS_SET_DPMS: string = "AS_SET_DPMS"; break;
|
||||||
case AS_GET_DPMS_STATE: string = "AS_GET_DPMS_STATE"; break;
|
case AS_GET_DPMS_STATE: string = "AS_GET_DPMS_STATE"; break;
|
||||||
case AS_GET_DPMS_CAPABILITIES: string = "AS_GET_DPMS_CAPABILITIES"; break;
|
case AS_GET_DPMS_CAPABILITIES: string = "AS_GET_DPMS_CAPABILITIES"; break;
|
||||||
@ -174,7 +176,7 @@ string_for_message_code(uint32 code, BString& string)
|
|||||||
case AS_GET_DECORATOR_SETTINGS: string = "AS_GET_DECORATOR_SETTINGS"; break;
|
case AS_GET_DECORATOR_SETTINGS: string = "AS_GET_DECORATOR_SETTINGS"; break;
|
||||||
case AS_GET_SHOW_ALL_DRAGGERS: string = "AS_GET_SHOW_ALL_DRAGGERS"; break;
|
case AS_GET_SHOW_ALL_DRAGGERS: string = "AS_GET_SHOW_ALL_DRAGGERS"; break;
|
||||||
case AS_SET_SHOW_ALL_DRAGGERS: string = "AS_SET_SHOW_ALL_DRAGGERS"; break;
|
case AS_SET_SHOW_ALL_DRAGGERS: string = "AS_SET_SHOW_ALL_DRAGGERS"; break;
|
||||||
|
|
||||||
// Subpixel antialiasing & hinting
|
// Subpixel antialiasing & hinting
|
||||||
case AS_SET_SUBPIXEL_ANTIALIASING: string = "AS_SET_SUBPIXEL_ANTIALIASING"; break;
|
case AS_SET_SUBPIXEL_ANTIALIASING: string = "AS_SET_SUBPIXEL_ANTIALIASING"; break;
|
||||||
case AS_GET_SUBPIXEL_ANTIALIASING: string = "AS_GET_SUBPIXEL_ANTIALIASING"; break;
|
case AS_GET_SUBPIXEL_ANTIALIASING: string = "AS_GET_SUBPIXEL_ANTIALIASING"; break;
|
||||||
@ -240,7 +242,6 @@ string_for_message_code(uint32 code, BString& string)
|
|||||||
case AS_VIEW_SET_ORIGIN: string = "AS_VIEW_SET_ORIGIN"; break;
|
case AS_VIEW_SET_ORIGIN: string = "AS_VIEW_SET_ORIGIN"; break;
|
||||||
case AS_VIEW_GET_ORIGIN: string = "AS_VIEW_GET_ORIGIN"; break;
|
case AS_VIEW_GET_ORIGIN: string = "AS_VIEW_GET_ORIGIN"; break;
|
||||||
case AS_VIEW_RESIZE_MODE: string = "AS_VIEW_RESIZE_MODE"; break;
|
case AS_VIEW_RESIZE_MODE: string = "AS_VIEW_RESIZE_MODE"; break;
|
||||||
case AS_VIEW_SET_CURSOR: string = "AS_VIEW_SET_CURSOR"; break;
|
|
||||||
case AS_VIEW_BEGIN_RECT_TRACK: string = "AS_VIEW_BEGIN_RECT_TRACK"; break;
|
case AS_VIEW_BEGIN_RECT_TRACK: string = "AS_VIEW_BEGIN_RECT_TRACK"; break;
|
||||||
case AS_VIEW_END_RECT_TRACK: string = "AS_VIEW_END_RECT_TRACK"; break;
|
case AS_VIEW_END_RECT_TRACK: string = "AS_VIEW_END_RECT_TRACK"; break;
|
||||||
case AS_VIEW_DRAG_RECT: string = "AS_VIEW_DRAG_RECT"; break;
|
case AS_VIEW_DRAG_RECT: string = "AS_VIEW_DRAG_RECT"; break;
|
||||||
@ -296,7 +297,7 @@ string_for_message_code(uint32 code, BString& string)
|
|||||||
// BDirectWindow codes
|
// BDirectWindow codes
|
||||||
case AS_DIRECT_WINDOW_GET_SYNC_DATA: string = "AS_DIRECT_WINDOW_GET_SYNC_DATA"; break;
|
case AS_DIRECT_WINDOW_GET_SYNC_DATA: string = "AS_DIRECT_WINDOW_GET_SYNC_DATA"; break;
|
||||||
case AS_DIRECT_WINDOW_SET_FULLSCREEN: string = "AS_DIRECT_WINDOW_SET_FULLSCREEN"; break;
|
case AS_DIRECT_WINDOW_SET_FULLSCREEN: string = "AS_DIRECT_WINDOW_SET_FULLSCREEN"; break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
string << "unkown code: " << code;
|
string << "unkown code: " << code;
|
||||||
break;
|
break;
|
||||||
|
@ -300,7 +300,17 @@ ServerApp::Activate(bool value)
|
|||||||
void
|
void
|
||||||
ServerApp::SetCurrentCursor(ServerCursor* cursor)
|
ServerApp::SetCurrentCursor(ServerCursor* cursor)
|
||||||
{
|
{
|
||||||
|
if (fViewCursor == cursor)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (fViewCursor)
|
||||||
|
fViewCursor->Release();
|
||||||
|
|
||||||
fViewCursor = cursor;
|
fViewCursor = cursor;
|
||||||
|
|
||||||
|
if (fViewCursor)
|
||||||
|
fViewCursor->Acquire();
|
||||||
|
|
||||||
fDesktop->SetCursor(CurrentCursor());
|
fDesktop->SetCursor(CurrentCursor());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -910,6 +920,63 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
case AS_SET_VIEW_CURSOR:
|
||||||
|
{
|
||||||
|
STRACE(("ServerApp %s: AS_SET_VIEW_CURSOR:\n", Signature()));
|
||||||
|
|
||||||
|
ViewSetViewCursorInfo info;
|
||||||
|
if (link.Read<ViewSetViewCursorInfo>(&info) != B_OK)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (fDesktop->GetCursorManager().Lock()) {
|
||||||
|
ServerCursor* cursor = fDesktop->GetCursorManager().FindCursor(
|
||||||
|
info.cursorToken);
|
||||||
|
// If we found a cursor, make sure it doesn't go away.
|
||||||
|
if (cursor != NULL)
|
||||||
|
cursor->Acquire();
|
||||||
|
|
||||||
|
fDesktop->GetCursorManager().Unlock();
|
||||||
|
|
||||||
|
if (cursor != NULL) {
|
||||||
|
// We need to acquire the write lock here, since we cannot
|
||||||
|
// afford that the window thread to which the view belongs
|
||||||
|
// is running and messing with that same view.
|
||||||
|
fDesktop->LockAllWindows();
|
||||||
|
|
||||||
|
// Find the corresponding view by the given token. It's ok
|
||||||
|
// if this view does not exist anymore, since it may have
|
||||||
|
// already be deleted in the window thread before this
|
||||||
|
// message got here.
|
||||||
|
View* view;
|
||||||
|
if (fViewTokens.GetToken(info.viewToken, B_HANDLER_TOKEN,
|
||||||
|
(void**)&view) == B_OK) {
|
||||||
|
// Set the cursor on the view.
|
||||||
|
view->SetCursor(cursor);
|
||||||
|
|
||||||
|
// The cursor might need to be updated now.
|
||||||
|
Window* window = view->Window();
|
||||||
|
if (window != NULL && window->IsFocus()) {
|
||||||
|
if (fDesktop->ViewUnderMouse(window)
|
||||||
|
== view->Token()) {
|
||||||
|
SetCurrentCursor(cursor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fDesktop->UnlockAllWindows();
|
||||||
|
|
||||||
|
// Release the temporary reference.
|
||||||
|
cursor->Release();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (info.sync) {
|
||||||
|
// sync the client (it can now delete the cursor)
|
||||||
|
fLink.StartMessage(B_OK);
|
||||||
|
fLink.Flush();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
case AS_CREATE_CURSOR:
|
case AS_CREATE_CURSOR:
|
||||||
{
|
{
|
||||||
STRACE(("ServerApp %s: Create Cursor\n", Signature()));
|
STRACE(("ServerApp %s: Create Cursor\n", Signature()));
|
||||||
@ -981,9 +1048,7 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
|||||||
// Attached data:
|
// Attached data:
|
||||||
// 1) int32 token ID of the cursor to delete
|
// 1) int32 token ID of the cursor to delete
|
||||||
int32 token;
|
int32 token;
|
||||||
bool pendingViewCursor;
|
if (link.Read<int32>(&token) != B_OK)
|
||||||
link.Read<int32>(&token);
|
|
||||||
if (link.Read<bool>(&pendingViewCursor) != B_OK)
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (!fDesktop->GetCursorManager().Lock())
|
if (!fDesktop->GetCursorManager().Lock())
|
||||||
@ -991,12 +1056,9 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
|
|||||||
|
|
||||||
ServerCursor* cursor
|
ServerCursor* cursor
|
||||||
= fDesktop->GetCursorManager().FindCursor(token);
|
= fDesktop->GetCursorManager().FindCursor(token);
|
||||||
if (cursor != NULL) {
|
if (cursor != NULL)
|
||||||
if (pendingViewCursor)
|
|
||||||
cursor->SetPendingViewCursor(true);
|
|
||||||
|
|
||||||
cursor->Release();
|
cursor->Release();
|
||||||
}
|
|
||||||
fDesktop->GetCursorManager().Unlock();
|
fDesktop->GetCursorManager().Unlock();
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
/*!
|
/*!
|
||||||
Although descended from ServerBitmaps, ServerCursors are not handled by
|
Although descended from ServerBitmaps, ServerCursors are not handled by
|
||||||
the BitmapManager - they are allocated like any other object. Unlike BeOS
|
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
|
R5, cursors can be any size or color space, and this class accomodates and
|
||||||
expands the R5 API.
|
expands the R5 API.
|
||||||
*/
|
*/
|
||||||
@ -33,19 +33,17 @@ using std::nothrow;
|
|||||||
\param flags ServerBitmap flags. See Bitmap.h.
|
\param flags ServerBitmap flags. See Bitmap.h.
|
||||||
\param hotspot Hotspot of the cursor
|
\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,
|
ServerCursor::ServerCursor(BRect r, color_space format, int32 flags,
|
||||||
int32 flags, BPoint hotspot,
|
BPoint hotspot, int32 bytesPerRow, screen_id screen)
|
||||||
int32 bytesPerRow,
|
:
|
||||||
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),
|
||||||
fReferenceCount(1),
|
fCursorData(NULL),
|
||||||
fCursorData(NULL),
|
fManager(NULL)
|
||||||
fManager(NULL),
|
|
||||||
fPendingViewCursor(0)
|
|
||||||
{
|
{
|
||||||
fHotSpot.ConstrainTo(Bounds());
|
fHotSpot.ConstrainTo(Bounds());
|
||||||
_AllocateBuffer();
|
_AllocateBuffer();
|
||||||
@ -57,13 +55,13 @@ ServerCursor::ServerCursor(BRect r, color_space format,
|
|||||||
\param data Pointer to 68-byte cursor data array. See BeBook entry for BCursor for details
|
\param data Pointer to 68-byte cursor data array. See BeBook entry for BCursor for details
|
||||||
*/
|
*/
|
||||||
ServerCursor::ServerCursor(const uint8* data)
|
ServerCursor::ServerCursor(const uint8* data)
|
||||||
: ServerBitmap(BRect(0, 0, 15, 15), B_RGBA32, 0),
|
:
|
||||||
fHotSpot(0, 0),
|
ServerBitmap(BRect(0, 0, 15, 15), B_RGBA32, 0),
|
||||||
fOwningTeam(-1),
|
fHotSpot(0, 0),
|
||||||
fReferenceCount(1),
|
fOwningTeam(-1),
|
||||||
fCursorData(NULL),
|
fReferenceCount(1),
|
||||||
fManager(NULL),
|
fCursorData(NULL),
|
||||||
fPendingViewCursor(0)
|
fManager(NULL)
|
||||||
{
|
{
|
||||||
// 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
|
||||||
@ -72,7 +70,7 @@ ServerCursor::ServerCursor(const uint8* data)
|
|||||||
// to RGBA32 (little endian). Eventually, there will be support for 16 and
|
// to RGBA32 (little endian). Eventually, there will be support for 16 and
|
||||||
// 8-bit depths
|
// 8-bit depths
|
||||||
// NOTE: review this once we have working PPC graphics cards (big endian).
|
// NOTE: review this once we have working PPC graphics cards (big endian).
|
||||||
if (data) {
|
if (data) {
|
||||||
_AllocateBuffer();
|
_AllocateBuffer();
|
||||||
uint8* buffer = Bits();
|
uint8* buffer = Bits();
|
||||||
if (!buffer)
|
if (!buffer)
|
||||||
@ -123,17 +121,16 @@ ServerCursor::ServerCursor(const uint8* data)
|
|||||||
\param data Pointer to bitmap data in memory,
|
\param data Pointer to bitmap data in memory,
|
||||||
the padding bytes should be contained when format less than 32 bpp.
|
the padding bytes should be contained when format less than 32 bpp.
|
||||||
*/
|
*/
|
||||||
ServerCursor::ServerCursor(const uint8* alreadyPaddedData,
|
ServerCursor::ServerCursor(const uint8* alreadyPaddedData, uint32 width,
|
||||||
uint32 width, uint32 height,
|
uint32 height, 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),
|
fReferenceCount(1),
|
||||||
fCursorData(NULL),
|
fCursorData(NULL),
|
||||||
fManager(NULL),
|
fManager(NULL)
|
||||||
fPendingViewCursor(0)
|
{
|
||||||
{
|
|
||||||
_AllocateBuffer();
|
_AllocateBuffer();
|
||||||
if (Bits())
|
if (Bits())
|
||||||
memcpy(Bits(), alreadyPaddedData, BitsLength());
|
memcpy(Bits(), alreadyPaddedData, BitsLength());
|
||||||
@ -145,19 +142,19 @@ ServerCursor::ServerCursor(const uint8* alreadyPaddedData,
|
|||||||
\param cursor cursor to copy
|
\param cursor cursor to copy
|
||||||
*/
|
*/
|
||||||
ServerCursor::ServerCursor(const ServerCursor* cursor)
|
ServerCursor::ServerCursor(const ServerCursor* cursor)
|
||||||
: ServerBitmap(cursor),
|
:
|
||||||
fHotSpot(0, 0),
|
ServerBitmap(cursor),
|
||||||
fOwningTeam(-1),
|
fHotSpot(0, 0),
|
||||||
fReferenceCount(1),
|
fOwningTeam(-1),
|
||||||
fCursorData(NULL),
|
fReferenceCount(1),
|
||||||
fManager(NULL),
|
fCursorData(NULL),
|
||||||
fPendingViewCursor(0)
|
fManager(NULL)
|
||||||
{
|
{
|
||||||
// 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.
|
||||||
_AllocateBuffer();
|
_AllocateBuffer();
|
||||||
|
|
||||||
if (cursor) {
|
if (cursor) {
|
||||||
if (Bits() && cursor->Bits())
|
if (Bits() && cursor->Bits())
|
||||||
memcpy(Bits(), cursor->Bits(), BitsLength());
|
memcpy(Bits(), cursor->Bits(), BitsLength());
|
||||||
fHotSpot = cursor->fHotSpot;
|
fHotSpot = cursor->fHotSpot;
|
||||||
@ -193,11 +190,6 @@ bool
|
|||||||
ServerCursor::Release()
|
ServerCursor::Release()
|
||||||
{
|
{
|
||||||
if (atomic_add(&fReferenceCount, -1) == 1) {
|
if (atomic_add(&fReferenceCount, -1) == 1) {
|
||||||
if (fPendingViewCursor > 0) {
|
|
||||||
// There is a SetViewCursor() waiting to be carried out
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (fManager && !fManager->RemoveCursor(this))
|
if (fManager && !fManager->RemoveCursor(this))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
@ -208,13 +200,6 @@ ServerCursor::Release()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
ServerCursor::SetPendingViewCursor(bool pending)
|
|
||||||
{
|
|
||||||
atomic_add(&fPendingViewCursor, pending ? 1 : -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ServerCursor::AttachedToManager(CursorManager* manager)
|
ServerCursor::AttachedToManager(CursorManager* manager)
|
||||||
{
|
{
|
||||||
|
@ -52,8 +52,6 @@ class ServerCursor : public ServerBitmap {
|
|||||||
bool Release();
|
bool Release();
|
||||||
int32 ReferenceCount() { return fReferenceCount; }
|
int32 ReferenceCount() { return fReferenceCount; }
|
||||||
|
|
||||||
void SetPendingViewCursor(bool pending);
|
|
||||||
|
|
||||||
void AttachedToManager(CursorManager* manager);
|
void AttachedToManager(CursorManager* manager);
|
||||||
|
|
||||||
const uint8* CursorData() const
|
const uint8* CursorData() const
|
||||||
@ -67,7 +65,6 @@ class ServerCursor : public ServerBitmap {
|
|||||||
vint32 fReferenceCount;
|
vint32 fReferenceCount;
|
||||||
uint8* fCursorData;
|
uint8* fCursorData;
|
||||||
CursorManager* fManager;
|
CursorManager* fManager;
|
||||||
vint32 fPendingViewCursor;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -1539,37 +1539,6 @@ fDesktop->LockSingleWindow();
|
|||||||
fCurrentView->SetResizeMode(resizeMode);
|
fCurrentView->SetResizeMode(resizeMode);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case AS_VIEW_SET_CURSOR:
|
|
||||||
{
|
|
||||||
DTRACE(("ServerWindow %s: Message AS_VIEW_CURSOR: View: %s\n",
|
|
||||||
Title(), fCurrentView->Name()));
|
|
||||||
|
|
||||||
ViewSetViewCursorInfo info;
|
|
||||||
if (link.Read<ViewSetViewCursorInfo>(&info) != B_OK)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if (!fDesktop->GetCursorManager().Lock())
|
|
||||||
break;
|
|
||||||
|
|
||||||
ServerCursor* cursor
|
|
||||||
= fDesktop->GetCursorManager().FindCursor(info.cursorToken);
|
|
||||||
fCurrentView->SetCursor(cursor);
|
|
||||||
|
|
||||||
fDesktop->GetCursorManager().Unlock();
|
|
||||||
|
|
||||||
if (fWindow->IsFocus()) {
|
|
||||||
// The cursor might need to be updated now
|
|
||||||
if (fDesktop->ViewUnderMouse(fWindow) == fCurrentView->Token())
|
|
||||||
fServerApp->SetCurrentCursor(cursor);
|
|
||||||
}
|
|
||||||
if (info.sync) {
|
|
||||||
// sync the client (it can now delete the cursor)
|
|
||||||
fLink.StartMessage(B_OK);
|
|
||||||
fLink.Flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case AS_VIEW_SET_FLAGS:
|
case AS_VIEW_SET_FLAGS:
|
||||||
{
|
{
|
||||||
uint32 flags;
|
uint32 flags;
|
||||||
|
@ -1291,10 +1291,8 @@ View::SetCursor(ServerCursor *cursor)
|
|||||||
|
|
||||||
fCursor = cursor;
|
fCursor = cursor;
|
||||||
|
|
||||||
if (fCursor) {
|
if (fCursor)
|
||||||
fCursor->Acquire();
|
fCursor->Acquire();
|
||||||
fCursor->SetPendingViewCursor(false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user