From aa1f5437999ab8531f33139c129c6bcaceb74e7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Sun, 5 Feb 2006 18:14:14 +0000 Subject: [PATCH] Some work on cursors: * Fixed a myriad of bugs all over the place, ranging from locking errors to deleting objects that don't belong to the one deleting them (hello HWInterface!) * Almost all ServerWindow cursor stuff was broken; I've replaced all commands to set a cursor with a single one AS_SET_CURSOR. * Renamed some cursor commands. * Changed the (broken) way ServerApp::fAppCursor was maintained - the application cursor is now NULL as long as possible. * Removed superfluous ServerCursor app signature stuff. * The BApplication will no longer duplicate the default/I-beam cursors, it will just reuse the default ones which now have fixed tokens. * As a result, changing the cursor is now working as expected, closing bug #102. * Rewrote Cursor.h, renamed private members to match our style guide. * Minor cleanup. What's still left to be done is reference counting the cursor objects to make them work right and reliable. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@16237 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/os/app/Cursor.h | 86 ++++---------- headers/private/app/ServerProtocol.h | 28 ++--- headers/private/servers/app/CursorSet.h | 57 ++++------ headers/private/servers/app/ServerBitmap.h | 41 +++---- headers/private/servers/app/ServerCursor.h | 67 +++-------- src/kits/app/Application.cpp | 34 ++---- src/kits/app/Cursor.cpp | 67 ++++++----- src/kits/app/Jamfile | 1 + src/kits/interface/View.cpp | 4 +- src/servers/app/CursorManager.cpp | 124 +++++++++------------ src/servers/app/CursorManager.h | 8 +- src/servers/app/CursorSet.cpp | 71 ++++++------ src/servers/app/ServerApp.cpp | 110 +++++++----------- src/servers/app/ServerBitmap.cpp | 15 ++- src/servers/app/ServerCursor.cpp | 58 +++++----- src/servers/app/ServerWindow.cpp | 14 +-- src/servers/app/WindowLayer.cpp | 10 +- src/servers/app/drawing/HWInterface.cpp | 20 +++- 18 files changed, 333 insertions(+), 482 deletions(-) diff --git a/headers/os/app/Cursor.h b/headers/os/app/Cursor.h index 5eff11ab04..8daebe5ad0 100644 --- a/headers/os/app/Cursor.h +++ b/headers/os/app/Cursor.h @@ -1,82 +1,40 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2001-2002, OpenBeOS -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// -// File Name: Cursor.h -// Author: Frans van Nispen (xlr8@tref.nl) -// Description: BCursor describes a view-wide or application-wide cursor. -//------------------------------------------------------------------------------ - +/* + * Copyright 2006, Haiku, Inc. All Rights Reserved. + * Distributed under the terms of the MIT License. + */ #ifndef _CURSOR_H #define _CURSOR_H -// Standard Includes ----------------------------------------------------------- -// System Includes ------------------------------------------------------------- #include -#include #include -// Project Includes ------------------------------------------------------------ -// Local Includes -------------------------------------------------------------- - -// Local Defines --------------------------------------------------------------- - -// Globals --------------------------------------------------------------------- - -// BCursor class --------------------------------------------------------------- class BCursor : BArchivable { -public: - BCursor(const void* cursorData); - BCursor(BMessage* data); - virtual ~BCursor(); + public: + BCursor(const void* cursorData); + BCursor(BMessage* data); + virtual ~BCursor(); - virtual status_t Archive(BMessage* into, bool deep = true) const; - static BArchivable* Instantiate(BMessage* data); + virtual status_t Archive(BMessage* archive, bool deep = true) const; + static BArchivable* Instantiate(BMessage* archive); -// Private or reserved --------------------------------------------------------- - virtual status_t Perform(perform_code d, void* arg); + private: + virtual status_t Perform(perform_code d, void* arg); -private: + virtual void _ReservedCursor1(); + virtual void _ReservedCursor2(); + virtual void _ReservedCursor3(); + virtual void _ReservedCursor4(); - virtual void _ReservedCursor1(); - virtual void _ReservedCursor2(); - virtual void _ReservedCursor3(); - virtual void _ReservedCursor4(); + private: + friend class BApplication; + friend class BView; - friend class BApplication; - friend class BView; + int32 fServerToken; + bool fNeedToFree; - int32 m_serverToken; - int32 m_needToFree; - uint32 _reserved[6]; + uint32 _reserved[6]; }; -//------------------------------------------------------------------------------ #endif // _CURSOR_H - -/* - * $Log $ - * - * $Id $ - * - */ - diff --git a/headers/private/app/ServerProtocol.h b/headers/private/app/ServerProtocol.h index a785f3ac9e..7dc75a63f3 100644 --- a/headers/private/app/ServerProtocol.h +++ b/headers/private/app/ServerProtocol.h @@ -1,13 +1,14 @@ /* - * Copyright 2001-2005, Haiku. + * Copyright 2001-2006, Haiku. * Distributed under the terms of the MIT License. * * Authors: * DarkWyrm * Jérôme Duval, jerome.duval@free.fr + * Axel Dörfler, axeld@pinc-software.de */ -#ifndef _APP_SERVER_PROTOCOL_H_ -#define _APP_SERVER_PROTOCOL_H_ +#ifndef APP_SERVER_PROTOCOL_H +#define APP_SERVER_PROTOCOL_H #include @@ -54,25 +55,16 @@ enum { AS_RELEASE_SERVERMEM, AS_AREA_MESSAGE, - // Cursor definitions - AS_SET_CURSOR_DATA, - AS_SET_CURSOR_BCURSOR, - AS_SET_CURSOR_BBITMAP, - AS_SET_CURSOR_SYSTEM, - - AS_SET_SYSCURSOR_DATA, - AS_SET_SYSCURSOR_BCURSOR, - AS_SET_SYSCURSOR_BBITMAP, - AS_SET_SYSCURSOR_DEFAULTS, - AS_GET_SYSCURSOR, + // Cursor commands + AS_SET_CURSOR, AS_SHOW_CURSOR, AS_HIDE_CURSOR, AS_OBSCURE_CURSOR, AS_QUERY_CURSOR_HIDDEN, - AS_CREATE_BCURSOR, - AS_DELETE_BCURSOR, + AS_CREATE_CURSOR, + AS_DELETE_CURSOR, AS_BEGIN_RECT_TRACKING, AS_END_RECT_TRACKING, @@ -260,7 +252,7 @@ enum { AS_LAYER_SET_ORIGIN, AS_LAYER_GET_ORIGIN, AS_LAYER_RESIZE_MODE, - AS_LAYER_CURSOR, + AS_LAYER_SET_CURSOR, AS_LAYER_BEGIN_RECT_TRACK, AS_LAYER_END_RECT_TRACK, AS_LAYER_DRAG_RECT, @@ -320,4 +312,4 @@ enum { AS_LAST_CODE }; -#endif // _APP_SERVER_PROTOCOL_H_ +#endif // APP_SERVER_PROTOCOL_H diff --git a/headers/private/servers/app/CursorSet.h b/headers/private/servers/app/CursorSet.h index 6b53a6c2c3..d3929efefa 100644 --- a/headers/private/servers/app/CursorSet.h +++ b/headers/private/servers/app/CursorSet.h @@ -1,39 +1,21 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2001-2005, Haiku -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// -// File Name: CursorSet.h -// Author: DarkWyrm -// Description: Private file encapsulating of the Haiku system cursor API -// -//------------------------------------------------------------------------------ -#ifndef CURSORSET_H_ -#define CURSORSET_H_ +/* + * Copyright 2001-2006, Haiku. + * Distributed under the terms of the MIT License. + * + * Authors: + * DarkWyrm + */ +#ifndef CURSOR_SET_H +#define CURSOR_SET_H + #include #include #include -typedef enum -{ - B_CURSOR_DEFAULT=0, + +typedef enum { + B_CURSOR_DEFAULT = 1, B_CURSOR_TEXT, B_CURSOR_MOVE, B_CURSOR_DRAG, @@ -49,15 +31,14 @@ typedef enum class ServerCursor; -const char *CursorWhichToString(cursor_which which); -BBitmap *CursorDataToBitmap(int8 *data); /*! \brief Class to manage system cursor sets */ class CursorSet : public BMessage { -public: - CursorSet(const char *name); + public: + CursorSet(const char *name); + status_t Save(const char *path,int32 saveflags=0); status_t Load(const char *path); status_t AddCursor(cursor_which which,const BBitmap *cursor, const BPoint &hotspot); @@ -67,6 +48,10 @@ public: status_t FindCursor(cursor_which which, ServerCursor **cursor); void SetName(const char *name); const char *GetName(void); + + private: + const char *_CursorWhichToString(cursor_which which); + BBitmap *_CursorDataToBitmap(int8 *data); }; -#endif +#endif // CURSOR_SET_H diff --git a/headers/private/servers/app/ServerBitmap.h b/headers/private/servers/app/ServerBitmap.h index 77d40446cf..84cdf6f1ae 100644 --- a/headers/private/servers/app/ServerBitmap.h +++ b/headers/private/servers/app/ServerBitmap.h @@ -1,5 +1,5 @@ /* - * Copyright 2001-2005, Haiku. + * Copyright 2001-2006, Haiku. * Distributed under the terms of the MIT License. * * Authors: @@ -26,51 +26,34 @@ class BitmapManager; */ class ServerBitmap { public: + inline bool IsValid() const + { return fInitialized; } + void Acquire(); - /*! - \brief Returns the area in which the buffer resides - \return - - \c B_ERROR if the buffer is not allocated in an area - - area_id for the buffer - */ inline area_id Area() const { return fArea; } - - // Returns the offset of the bitmap in its area inline int32 AreaOffset() const { return fOffset; } - //! Returns the bitmap's buffer inline uint8* Bits() const { return fBuffer; } - inline uint32 BitsLength() const { return (uint32)(fBytesPerRow * fHeight); } inline BRect Bounds() const { return BRect(0, 0, fWidth - 1, fHeight - 1); } - - //! Returns the number of bytes in each row, including padding - inline int32 BytesPerRow() const - { return fBytesPerRow; } - - inline uint8 BitsPerPixel() const - { return fBitsPerPixel; } - - inline color_space ColorSpace() const - { return fSpace; } - - //! Returns the bitmap's width in pixels per row inline int32 Width() const { return fWidth; } - - //! Returns the bitmap's row count inline int32 Height() const { return fHeight; } - inline bool IsValid() const - { return fInitialized; } + inline int32 BytesPerRow() const + { return fBytesPerRow; } + inline uint8 BitsPerPixel() const + { return fBitsPerPixel; } + inline color_space ColorSpace() const + { return fSpace; } //! Returns the identifier token for the bitmap inline int32 Token() const @@ -79,6 +62,8 @@ class ServerBitmap { //! Does a shallow copy of the bitmap passed to it inline void ShallowCopy(const ServerBitmap *from); + void PrintToStream(); + protected: friend class BitmapManager; friend class PicturePlayer; @@ -86,7 +71,7 @@ protected: ServerBitmap(BRect rect, color_space space, int32 flags, - int32 bytesperline = -1, + int32 bytesPerRow = -1, screen_id screen = B_MAIN_SCREEN_ID); ServerBitmap(const ServerBitmap* bmp); virtual ~ServerBitmap(); diff --git a/headers/private/servers/app/ServerCursor.h b/headers/private/servers/app/ServerCursor.h index 1473b9c2f4..bbd5b2fdf8 100644 --- a/headers/private/servers/app/ServerCursor.h +++ b/headers/private/servers/app/ServerCursor.h @@ -1,50 +1,25 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2001-2002, Haiku, Inc. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// -// File Name: ServerCursor.h -// Author: DarkWyrm -// Stephan Aßmus -// Description: Glorified ServerBitmap used for cursor work. -// -//------------------------------------------------------------------------------ -#ifndef SERVERCURSOR_H_ -#define SERVERCURSOR_H_ +/* + * Copyright 2001-2006, Haiku. + * Distributed under the terms of the MIT License. + * + * Authors: + * DarkWyrm + * Stephan Aßmus + * Axel Dörfler, axeld@pinc-software.de + */ +#ifndef SERVER_CURSOR_H +#define SERVER_CURSOR_H + + +#include "ServerBitmap.h" #include #include -#include "ServerBitmap.h" - class ServerApp; class CursorManager; -/*! - \class ServerCursor ServerCursor.h - \brief Class to handle all cursor capabilities for the system - - Although descended from ServerBitmaps, ServerCursors are not handled by - 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 - expands the R5 API. -*/ + class ServerCursor : public ServerBitmap { public: ServerCursor(BRect r, color_space space, @@ -64,24 +39,18 @@ class ServerCursor : public ServerBitmap { BPoint GetHotSpot() const { return fHotSpot; } - void SetAppSignature(const char* signature); - const char* GetAppSignature() const - { return fAppSignature.String(); } - void SetOwningTeam(team_id tid) { fOwningTeam = tid; } team_id OwningTeam() const { return fOwningTeam; } - - //! Returns the cursor's ID - int32 ID() const + + int32 Token() const { return fToken; } private: friend class CursorManager; BPoint fHotSpot; team_id fOwningTeam; - BString fAppSignature; }; -#endif // SERVERCURSOR_H_ +#endif // SERVER_CURSOR_H diff --git a/src/kits/app/Application.cpp b/src/kits/app/Application.cpp index 5e6a7fd4c0..a21bdc64d3 100644 --- a/src/kits/app/Application.cpp +++ b/src/kits/app/Application.cpp @@ -666,13 +666,11 @@ BApplication::IsCursorHidden() const void -BApplication::SetCursor(const void *cursor) +BApplication::SetCursor(const void *cursorData) { - // BeBook sez: If you want to call SetCursor() without forcing an immediate - // sync of the Application Server, you have to use a BCursor. - // By deductive reasoning, this function forces a sync. =) - BCursor Cursor(cursor); - SetCursor(&Cursor, true); + BCursor cursor(cursorData); + SetCursor(&cursor, true); + // forces the cursor to be sync'ed } @@ -680,14 +678,14 @@ void BApplication::SetCursor(const BCursor *cursor, bool sync) { BPrivate::AppServerLink link; - int32 code = SERVER_FALSE; - - link.StartMessage(AS_SET_CURSOR_BCURSOR); + link.StartMessage(AS_SET_CURSOR); link.Attach(sync); - link.Attach(cursor->m_serverToken); - if (sync) + link.Attach(cursor->fServerToken); + + if (sync) { + int32 code; link.FlushWithReply(code); - else + } else link.Flush(); } @@ -695,24 +693,16 @@ BApplication::SetCursor(const BCursor *cursor, bool sync) int32 BApplication::CountWindows() const { - // BeBook sez: The windows list includes all windows explicitely created by - // the app ... but excludes private windows create by Be - // classes. - // I'm taking this to include private menu windows, thus the incl_menus - // param is false. return count_windows(false); + // we're ignoring menu windows } BWindow * BApplication::WindowAt(int32 index) const { - // BeBook sez: The windows list includes all windows explicitely created by - // the app ... but excludes private windows create by Be - // classes. - // I'm taking this to include private menu windows, thus the incl_menus - // param is false. return window_at(index, false); + // we're ignoring menu windows } diff --git a/src/kits/app/Cursor.cpp b/src/kits/app/Cursor.cpp index 2e69118c1a..da9b9baae4 100644 --- a/src/kits/app/Cursor.cpp +++ b/src/kits/app/Cursor.cpp @@ -1,10 +1,11 @@ /* - * Copyright 2001-2005, Haiku. + * Copyright 2001-2006, Haiku. * Distributed under the terms of the MIT License. * * Authors: * Frans van Nispen (xlr8@tref.nl) * Gabe Yoder (gyoder@stny.rr.com) + * Axel Dörfler, axeld@pinc-software.de */ /** BCursor describes a view-wide or application-wide cursor. */ @@ -15,8 +16,9 @@ */ #include - #include + +#include #include #include @@ -27,9 +29,20 @@ const BCursor *B_CURSOR_I_BEAM; BCursor::BCursor(const void *cursorData) + : + fServerToken(-1), + fNeedToFree(false) { - int8 *data = (int8 *)cursorData; - m_serverToken = 0; + const uint8 *data = (const uint8 *)cursorData; + + if (data == B_HAND_CURSOR || data == B_I_BEAM_CURSOR) { + // just use the default cursors from the app_server + fServerToken = data == B_HAND_CURSOR ? + B_CURSOR_DEFAULT : B_CURSOR_TEXT; + return; + } + + // Create a new cursor in the app_server if (data == NULL || data[0] != 16 // size @@ -38,47 +51,50 @@ BCursor::BCursor(const void *cursorData) return; // Send data directly to server - BPrivate::AppServerLink serverlink; - int32 code = SERVER_FALSE; + BPrivate::AppServerLink link; + link.StartMessage(AS_CREATE_CURSOR); + link.Attach(cursorData, 68); - serverlink.StartMessage(AS_CREATE_BCURSOR); - serverlink.Attach(cursorData, 68); - serverlink.FlushWithReply(code); - if (code == SERVER_TRUE) - serverlink.Read(&m_serverToken); + status_t status; + if (link.FlushWithReply(status) == B_OK && status == B_OK) { + link.Read(&fServerToken); + fNeedToFree = true; + } } -// undefined on BeOS - BCursor::BCursor(BMessage *data) { - m_serverToken = 0; + // undefined on BeOS + fServerToken = -1; + fNeedToFree = false; } BCursor::~BCursor() { // Notify server to deallocate server-side objects for this cursor - BPrivate::AppServerLink serverlink; - serverlink.StartMessage(AS_DELETE_BCURSOR); - serverlink.Attach(m_serverToken); - serverlink.Flush(); + if (fNeedToFree) { + BPrivate::AppServerLink link; + link.StartMessage(AS_DELETE_CURSOR); + link.Attach(fServerToken); + link.Flush(); + } } -// not implemented on BeOS - -status_t BCursor::Archive(BMessage *into, bool deep) const +status_t +BCursor::Archive(BMessage *into, bool deep) const { + // not implemented on BeOS return B_OK; } -// not implemented on BeOS - -BArchivable *BCursor::Instantiate(BMessage *data) +BArchivable * +BCursor::Instantiate(BMessage *data) { + // not implemented on BeOS return NULL; } @@ -86,9 +102,6 @@ BArchivable *BCursor::Instantiate(BMessage *data) status_t BCursor::Perform(perform_code d, void *arg) { - /* - printf("perform %d\n", (int)d); - */ return B_OK; } diff --git a/src/kits/app/Jamfile b/src/kits/app/Jamfile index 40208c76e4..df366bc67a 100644 --- a/src/kits/app/Jamfile +++ b/src/kits/app/Jamfile @@ -19,6 +19,7 @@ if $(RUN_WITHOUT_APP_SERVER) != 0 { UsePrivateHeaders shared app interface ; UsePrivateHeaders [ FDirName kernel util ] ; # For KMessage.h +UsePrivateHeaders [ FDirName servers app ] ; SetSubDirSupportedPlatforms haiku libbe_test ; diff --git a/src/kits/interface/View.cpp b/src/kits/interface/View.cpp index ff62c98595..f58f9a22fa 100644 --- a/src/kits/interface/View.cpp +++ b/src/kits/interface/View.cpp @@ -1004,8 +1004,8 @@ BView::SetViewCursor(const BCursor *cursor, bool sync) check_lock(); - fOwner->fLink->StartMessage(AS_LAYER_CURSOR); - fOwner->fLink->Attach(cursor->m_serverToken); + fOwner->fLink->StartMessage(AS_LAYER_SET_CURSOR); + fOwner->fLink->Attach(cursor->fServerToken); if (sync) fOwner->fLink->Flush(); diff --git a/src/servers/app/CursorManager.cpp b/src/servers/app/CursorManager.cpp index b294467d7d..558887c16e 100644 --- a/src/servers/app/CursorManager.cpp +++ b/src/servers/app/CursorManager.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2001-2005, Haiku. + * Copyright 2001-2006, Haiku. * Distributed under the terms of the MIT License. * * Authors: @@ -9,9 +9,6 @@ /** Handles the system's cursor infrastructure */ -#include -#include - #include "CursorData.h" #include "CursorManager.h" #include "HaikuSystemCursor.h" @@ -19,10 +16,13 @@ #include "ServerConfig.h" #include "ServerTokenSpace.h" +#include +#include +#include + -//! Initializes the CursorManager CursorManager::CursorManager() - : BLocker("CursorManager") + : BLocker("CursorManager") { // Set system cursors to "unassigned" // ToDo: decide about default cursor @@ -34,11 +34,11 @@ CursorManager::CursorManager() fDefaultCursor->SetHotSpot(BPoint(1, 0)); #else fDefaultCursor = new ServerCursor(default_cursor_data); - AddCursor(fDefaultCursor); #endif + AddCursor(fDefaultCursor, B_CURSOR_DEFAULT); fTextCursor = new ServerCursor(default_text_data); - AddCursor(fTextCursor); + AddCursor(fTextCursor, B_CURSOR_TEXT); fMoveCursor = new ServerCursor(default_move_data); AddCursor(fMoveCursor); @@ -67,16 +67,8 @@ CursorManager::CursorManager() CursorManager::~CursorManager() { for (int32 i = 0; i < fCursorList.CountItems(); i++) { - ServerCursor *cursor = (ServerCursor *)fCursorList.ItemAt(i); - if (cursor) - delete cursor; + delete (ServerCursor *)fCursorList.ItemAt(i); } - - // Note that it is not necessary to remove and delete the system - // cursors. These cursors are kept in the list with a empty application - // signature so they cannot be removed very easily except via - // SetCursor(cursor_which). At shutdown, they are removed with the - // above loop. } @@ -86,7 +78,7 @@ CursorManager::~CursorManager() \return The token assigned to the cursor or B_ERROR if sc is NULL */ int32 -CursorManager::AddCursor(ServerCursor* cursor) +CursorManager::AddCursor(ServerCursor* cursor, int32 token) { if (!cursor) return B_ERROR; @@ -94,17 +86,32 @@ CursorManager::AddCursor(ServerCursor* cursor) Lock(); fCursorList.AddItem(cursor); - int32 token = fTokenSpace.NewToken(B_SERVER_TOKEN, cursor); - cursor->fToken = token; + if (token == -1) + cursor->fToken = fTokenSpace.NewToken(kCursorToken, cursor); + else { + fTokenSpace.SetToken(token, kCursorToken, cursor); + cursor->fToken = token; + } Unlock(); return token; } +ServerCursor* +CursorManager::_RemoveCursor(int32 index) +{ + ServerCursor* cursor = (ServerCursor *)fCursorList.RemoveItem(index); + if (cursor != NULL) + fTokenSpace.RemoveToken(cursor->fToken); + + return cursor; +} + + /*! \brief Removes a cursor from the internal list and deletes it - \param token ID value of the cursor to be deleted + \param token Token of the cursor to be deleted If the cursor is not found, this call does nothing */ @@ -113,11 +120,11 @@ CursorManager::DeleteCursor(int32 token) { Lock(); - for (int32 i = 0; i < fCursorList.CountItems(); i++) { - ServerCursor *cursor = (ServerCursor *)fCursorList.ItemAt(i); + for (int32 index = 0; index < fCursorList.CountItems(); index++) { + ServerCursor *cursor = (ServerCursor *)fCursorList.ItemAt(index); if (cursor && cursor->fToken == token) { - fCursorList.RemoveItem(i); + _RemoveCursor(index); delete cursor; break; } @@ -132,21 +139,17 @@ CursorManager::DeleteCursor(int32 token) \param signature Signature to which the cursors belong */ void -CursorManager::RemoveAppCursors(team_id team) +CursorManager::DeleteCursors(team_id team) { Lock(); - int32 index = 0; - while (index < fCursorList.CountItems()) { + for (int32 index = fCursorList.CountItems(); index-- > 0;) { ServerCursor *cursor = (ServerCursor *)fCursorList.ItemAt(index); - if (!cursor) - break; + if (cursor->OwningTeam() != team) + continue; - if (cursor->OwningTeam() == team) { - fCursorList.RemoveItem(index); - delete cursor; - } else - index++; + _RemoveCursor(index); + delete cursor; } Unlock(); @@ -165,7 +168,8 @@ CursorManager::RemoveAppCursors(team_id team) void CursorManager::SetCursorSet(const char *path) { - Lock(); + BAutolock locker (this); + CursorSet cursorSet(NULL); if (!path || cursorSet.Load(path) != B_OK) @@ -226,8 +230,6 @@ CursorManager::SetCursorSet(const char *path) delete fEWCursor; fEWCursor = cursor; } - - Unlock(); } @@ -240,52 +242,31 @@ CursorManager::SetCursorSet(const char *path) ServerCursor * CursorManager::GetCursor(cursor_which which) { - ServerCursor *cursor = NULL; - Lock(); + BAutolock locker(this); switch (which) { case B_CURSOR_DEFAULT: - cursor = fDefaultCursor; - break; - + return fDefaultCursor; case B_CURSOR_TEXT: - cursor = fTextCursor; - break; - + return fTextCursor; case B_CURSOR_MOVE: - cursor = fMoveCursor; - break; - + return fMoveCursor; case B_CURSOR_DRAG: - cursor = fDragCursor; - break; - + return fDragCursor; case B_CURSOR_RESIZE: - cursor = fResizeCursor; - break; - + return fResizeCursor; case B_CURSOR_RESIZE_NWSE: - cursor = fNWSECursor; - break; - + return fNWSECursor; case B_CURSOR_RESIZE_NESW: - cursor = fNESWCursor; - break; - + return fNESWCursor; case B_CURSOR_RESIZE_NS: - cursor = fNSCursor; - break; - + return fNSCursor; case B_CURSOR_RESIZE_EW: - cursor = fEWCursor; - break; + return fEWCursor; default: - break; + return NULL; } - - Unlock(); - return cursor; } @@ -382,9 +363,6 @@ CursorManager::ChangeCursor(cursor_which which, int32 token) return; } - if (cursor->GetAppSignature()) - cursor->SetAppSignature(""); - fCursorList.RemoveItem(cursor); Unlock(); } @@ -399,7 +377,7 @@ ServerCursor * CursorManager::FindCursor(int32 token) { ServerCursor* cursor; - if (gTokenSpace.GetToken(token, kCursorToken, (void**)&cursor) == B_OK) + if (fTokenSpace.GetToken(token, kCursorToken, (void**)&cursor) == B_OK) return cursor; return NULL; diff --git a/src/servers/app/CursorManager.h b/src/servers/app/CursorManager.h index e201be77d5..1191bd1397 100644 --- a/src/servers/app/CursorManager.h +++ b/src/servers/app/CursorManager.h @@ -1,5 +1,5 @@ /* - * Copyright 2001-2005, Haiku. + * Copyright 2001-2006, Haiku. * Distributed under the terms of the MIT License. * * Authors: @@ -33,9 +33,9 @@ class CursorManager : public BLocker { CursorManager(); virtual ~CursorManager(); - int32 AddCursor(ServerCursor* cursor); + int32 AddCursor(ServerCursor* cursor, int32 token = -1); void DeleteCursor(int32 token); - void RemoveAppCursors(team_id team); + void DeleteCursors(team_id team); void SetCursorSet(const char* path); ServerCursor* GetCursor(cursor_which which); @@ -45,6 +45,8 @@ class CursorManager : public BLocker { ServerCursor* FindCursor(int32 token); private: + ServerCursor* _RemoveCursor(int32 index); + BList fCursorList; BTokenSpace fTokenSpace; diff --git a/src/servers/app/CursorSet.cpp b/src/servers/app/CursorSet.cpp index 3c63ee3c0e..dc4b60bcdf 100644 --- a/src/servers/app/CursorSet.cpp +++ b/src/servers/app/CursorSet.cpp @@ -1,37 +1,21 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2001-2005, Haiku, Inc. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// -// File Name: CursorSet.cpp -// Author: DarkWyrm -// Description: Private file encapsulating OBOS system cursor API -// -//------------------------------------------------------------------------------ -#include +/* + * Copyright 2001-2006, Haiku. + * Distributed under the terms of the MIT License. + * + * Authors: + * DarkWyrm + */ + + #include +#include +#include +#include #include + #include #include #include -#include "CursorSet.h" -#include "ServerCursor.h" /*! @@ -44,6 +28,7 @@ CursorSet::CursorSet(const char *name) AddString("name", name ? name : "Untitled"); } + /*! \brief Saves the data in the cursor set to a file \param path Path of the file to save to. @@ -54,19 +39,20 @@ CursorSet::CursorSet(const char *name) - \c other value: See BFile::SetTo and BMessage::Flatten return codes */ status_t -CursorSet::Save(const char *path, int32 saveflags) +CursorSet::Save(const char *path, int32 saveFlags) { if (!path) return B_BAD_VALUE; BFile file; - status_t status = file.SetTo(path, B_READ_WRITE | saveflags); + status_t status = file.SetTo(path, B_READ_WRITE | saveFlags); if (status != B_OK) return status; return Flatten(&file); } + /*! \brief Loads the data into the cursor set from a file \param path Path of the file to load from. @@ -89,6 +75,7 @@ CursorSet::Load(const char *path) return Unflatten(&file); } + /*! \brief Adds the cursor to the set and replaces any existing entry for the given specifier \param which System cursor specifier defined in CursorSet.h @@ -103,7 +90,7 @@ CursorSet::AddCursor(cursor_which which, const BBitmap *cursor, const BPoint &ho return B_BAD_VALUE; // Remove the data if it exists already - RemoveData(CursorWhichToString(which)); + RemoveData(_CursorWhichToString(which)); // Actually add the data to our set BMessage msg((int32)which); @@ -116,11 +103,12 @@ CursorSet::AddCursor(cursor_which which, const BBitmap *cursor, const BPoint &ho msg.AddInt32("_rowbytes",cursor->BytesPerRow()); msg.AddPoint("hotspot",hotspot); msg.AddData("_data",B_RAW_TYPE,cursor->Bits(), cursor->BitsLength()); - AddMessage(CursorWhichToString(which),&msg); + AddMessage(_CursorWhichToString(which),&msg); return B_OK; } + /*! \brief Adds the cursor to the set and replaces any existing entry for the given specifier \param which System cursor specifier defined in CursorSet.h @@ -138,7 +126,7 @@ CursorSet::AddCursor(cursor_which which, int8 *data) if (!data) return B_BAD_VALUE; - BBitmap *bmp = CursorDataToBitmap(data); + BBitmap *bmp = _CursorDataToBitmap(data); BPoint pt(data[2],data[3]); status_t stat = AddCursor(which,bmp,pt); @@ -147,6 +135,7 @@ CursorSet::AddCursor(cursor_which which, int8 *data) return stat; } + /*! \brief Removes the data associated with the specifier from the cursor set \param which System cursor specifier defined in CursorSet.h @@ -154,9 +143,10 @@ CursorSet::AddCursor(cursor_which which, int8 *data) void CursorSet::RemoveCursor(cursor_which which) { - RemoveData(CursorWhichToString(which)); + RemoveData(_CursorWhichToString(which)); } + /*! \brief Retrieves a cursor from the set. \param which System cursor specifier defined in CursorSet.h @@ -177,7 +167,7 @@ CursorSet::FindCursor(cursor_which which, BBitmap **cursor, BPoint *hotspot) return B_BAD_VALUE; BMessage msg; - if (FindMessage(CursorWhichToString(which), &msg) != B_OK) + if (FindMessage(_CursorWhichToString(which), &msg) != B_OK) return B_NAME_NOT_FOUND; const void *buffer; @@ -206,6 +196,7 @@ CursorSet::FindCursor(cursor_which which, BBitmap **cursor, BPoint *hotspot) return B_ERROR; } + /*! \brief Retrieves a cursor from the set. \param which System cursor specifier defined in CursorSet.h @@ -222,7 +213,7 @@ status_t CursorSet::FindCursor(cursor_which which, ServerCursor **_cursor) { BMessage msg; - if (FindMessage(CursorWhichToString(which), &msg) != B_OK) + if (FindMessage(_CursorWhichToString(which), &msg) != B_OK) return B_NAME_NOT_FOUND; const char *className; @@ -250,6 +241,7 @@ CursorSet::FindCursor(cursor_which which, ServerCursor **_cursor) return B_ERROR; } + /*! \brief Returns the name of the set \return The name of the set @@ -264,6 +256,7 @@ CursorSet::GetName(void) return NULL; } + /*! \brief Renames the cursor set \param name new name of the set. @@ -287,7 +280,7 @@ CursorSet::SetName(const char *name) \return Name for the cursor specifier */ const char * -CursorWhichToString(cursor_which which) +CursorSet::_CursorWhichToString(cursor_which which) { switch (which) { case B_CURSOR_DEFAULT: @@ -323,7 +316,7 @@ CursorWhichToString(cursor_which which) BBitmaps returned by this function are always in the RGBA32 color space */ BBitmap * -CursorDataToBitmap(int8 *data) +CursorSet::_CursorDataToBitmap(int8 *data) { // 68-byte array used in R5 for holding cursors. // This API has serious problems and should be deprecated(but supported) in R2 diff --git a/src/servers/app/ServerApp.cpp b/src/servers/app/ServerApp.cpp index b643a00769..fc051fcefb 100644 --- a/src/servers/app/ServerApp.cpp +++ b/src/servers/app/ServerApp.cpp @@ -118,14 +118,6 @@ ServerApp::ServerApp(Desktop* desktop, port_id clientReplyPort, BMessenger::Private(fHandlerMessenger).SetTo(fClientTeam, clientLooperPort, clientToken); - ServerCursor *defaultCursor = - fDesktop->GetCursorManager().GetCursor(B_CURSOR_DEFAULT); - - if (defaultCursor) { - fAppCursor = new ServerCursor(defaultCursor); - fAppCursor->SetOwningTeam(fClientTeam); - } - fInitialWorkspace = desktop->CurrentWorkspace(); // TODO: this should probably be retrieved when the app is loaded! @@ -191,7 +183,7 @@ ServerApp::~ServerApp() delete (ServerPicture*)fPictureList.ItemAtFast(i); } - fDesktop->GetCursorManager().RemoveAppCursors(fClientTeam); + fDesktop->GetCursorManager().DeleteCursors(fClientTeam); STRACE(("ServerApp %s::~ServerApp(): Exiting\n", Signature())); } @@ -298,9 +290,8 @@ ServerApp::Activate(bool value) void ServerApp::SetCursor() { -// TODO: custom cursors cannot be drawn by the HWInterface right now (wrong bitmap format) -// if (fAppCursor) -// fDesktop->HWInterface()->SetCursor(fAppCursor); + if (fAppCursor != NULL) + fDesktop->HWInterface()->SetCursor(fAppCursor); fDesktop->HWInterface()->SetCursorVisible(fCursorHideLevel == 0); } @@ -886,95 +877,76 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link) fLink.Flush(); break; } - case AS_SET_CURSOR_DATA: + case AS_SET_CURSOR: { - STRACE(("ServerApp %s: SetCursor via cursor data\n", Signature())); - // Attached data: 68 bytes of fAppCursor data - - int8 cursorData[68]; - link.Read(cursorData, 68); - - // Because we don't want an overaccumulation of these particular - // cursors, we will delete them if there is an existing one. It would - // otherwise be easy to crash the server by calling SetCursor a - // sufficient number of times - if (fAppCursor) - fDesktop->GetCursorManager().DeleteCursor(fAppCursor->ID()); - - fAppCursor = new ServerCursor(cursorData); - fAppCursor->SetOwningTeam(fClientTeam); - fAppCursor->SetAppSignature(Signature()); - - // ToDo: These two should probably both be done in Desktop directly - fDesktop->GetCursorManager().AddCursor(fAppCursor); - fDesktop->HWInterface()->SetCursor(fAppCursor); - break; - } - case AS_SET_CURSOR_BCURSOR: - { - STRACE(("ServerApp %s: SetCursor via BCursor\n", Signature())); + STRACE(("ServerApp %s: SetCursor\n", Signature())); // Attached data: // 1) bool flag to send a reply // 2) int32 token ID of the cursor to set // 3) port_id port to receive a reply. Only exists if the sync flag is true. bool sync; - int32 ctoken = B_NULL_TOKEN; - - link.Read(&sync); - link.Read(&ctoken); + int32 token = B_NULL_TOKEN; - ServerCursor *cursor = fDesktop->GetCursorManager().FindCursor(ctoken); - if (cursor) - fDesktop->HWInterface()->SetCursor(cursor); + link.Read(&sync); + link.Read(&token); + + fAppCursor = fDesktop->GetCursorManager().FindCursor(token); + if (fAppCursor != NULL) + fDesktop->HWInterface()->SetCursor(fAppCursor); + else { + // if there is no new cursor, we just set the default cursor + fDesktop->HWInterface()->SetCursor(fDesktop->GetCursorManager().GetCursor(B_CURSOR_DEFAULT)); + } if (sync) { - // the application is expecting a reply so that it - // knows the cursor shape has truely changed + // The application is expecting a reply fLink.StartMessage(B_OK); fLink.Flush(); } break; } - case AS_CREATE_BCURSOR: + case AS_CREATE_CURSOR: { - STRACE(("ServerApp %s: Create BCursor\n", Signature())); + STRACE(("ServerApp %s: Create Cursor\n", Signature())); // Attached data: // 1) 68 bytes of fAppCursor data // 2) port_id reply port - + + status_t status = B_ERROR; int8 cursorData[68]; - link.Read(cursorData, sizeof(cursorData)); + ServerCursor* cursor = NULL; - // Because we don't want an overaccumulation of these particular - // cursors, we will delete them if there is an existing one. It would - // otherwise be easy to crash the server by calling CreateCursor a - // sufficient number of times - if (fAppCursor) - fDesktop->GetCursorManager().DeleteCursor(fAppCursor->ID()); + if (link.Read(cursorData, sizeof(cursorData)) >= B_OK) { + cursor = new (nothrow) ServerCursor(cursorData); + if (cursor == NULL) + status = B_NO_MEMORY; + } - fAppCursor = new ServerCursor(cursorData); - fAppCursor->SetOwningTeam(fClientTeam); - fAppCursor->SetAppSignature(Signature()); - fDesktop->GetCursorManager().AddCursor(fAppCursor); + if (cursor != NULL) { + cursor->SetOwningTeam(fClientTeam); + fDesktop->GetCursorManager().AddCursor(cursor); + + // Synchronous message - BApplication is waiting on the cursor's ID + fLink.StartMessage(B_OK); + fLink.Attach(cursor->Token()); + } else + fLink.StartMessage(status); - // Synchronous message - BApplication is waiting on the cursor's ID - fLink.StartMessage(B_OK); - fLink.Attach(fAppCursor->ID()); fLink.Flush(); break; } - case AS_DELETE_BCURSOR: + case AS_DELETE_CURSOR: { STRACE(("ServerApp %s: Delete BCursor\n", Signature())); // Attached data: // 1) int32 token ID of the cursor to delete - int32 ctoken = B_NULL_TOKEN; - link.Read(&ctoken); + int32 token = B_NULL_TOKEN; + link.Read(&token); - if (fAppCursor && fAppCursor->ID() == ctoken) + if (fAppCursor && fAppCursor->Token() == token) fAppCursor = NULL; - fDesktop->GetCursorManager().DeleteCursor(ctoken); + fDesktop->GetCursorManager().DeleteCursor(token); break; } diff --git a/src/servers/app/ServerBitmap.cpp b/src/servers/app/ServerBitmap.cpp index 408cf59b62..1af141677a 100644 --- a/src/servers/app/ServerBitmap.cpp +++ b/src/servers/app/ServerBitmap.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2001-2005, Haiku. + * Copyright 2001-2006, Haiku. * Distributed under the terms of the MIT License. * * Authors: @@ -10,6 +10,7 @@ #include "ServerBitmap.h" #include +#include #include using std::nothrow; @@ -26,7 +27,7 @@ using std::nothrow; \param screen Screen assigned to the bitmap. */ ServerBitmap::ServerBitmap(BRect rect, color_space space, - int32 flags, int32 bytesPerLine, + int32 flags, int32 bytesPerRow, screen_id screen) : fInitialized(false), fArea(B_ERROR), @@ -44,7 +45,7 @@ ServerBitmap::ServerBitmap(BRect rect, color_space space, fBitsPerPixel(0) // TODO: what about fToken and fOffset ?!? { - _HandleSpace(space, bytesPerLine); + _HandleSpace(space, bytesPerRow); } @@ -244,6 +245,14 @@ ServerBitmap::_HandleSpace(color_space space, int32 bytesPerRow) } +void +ServerBitmap::PrintToStream() +{ + printf("Bitmap@%p: (%ld:%ld), space %ld, bpr %ld, buffer %p\n", + this, fWidth, fHeight, (int32)fSpace, fBytesPerRow, fBuffer); +} + + // #pragma mark - diff --git a/src/servers/app/ServerCursor.cpp b/src/servers/app/ServerCursor.cpp index bd2c62c9ed..61aa95f811 100644 --- a/src/servers/app/ServerCursor.cpp +++ b/src/servers/app/ServerCursor.cpp @@ -1,32 +1,25 @@ -//------------------------------------------------------------------------------ -// Copyright (c) 2001-2002, Haiku, Inc. -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -// DEALINGS IN THE SOFTWARE. -// -// File Name: ServerCursor.cpp -// Author: DarkWyrm -// Stephan Aßmus -// Description: Glorified ServerBitmap used for cursor work. -// -//------------------------------------------------------------------------------ +/* + * Copyright 2001-2006, Haiku. + * Distributed under the terms of the MIT License. + * + * Authors: + * DarkWyrm + * Stephan Aßmus + * Axel Dörfler, axeld@pinc-software.de + */ + +/*! + Although descended from ServerBitmaps, ServerCursors are not handled by + 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 + expands the R5 API. +*/ + #include "ServerCursor.h" + #include + + /*! \brief Constructor \param r Size of the cursor @@ -48,6 +41,7 @@ ServerCursor::ServerCursor(BRect r, color_space format, _AllocateBuffer(); } + /*! \brief Constructor \param data Pointer to 68-byte cursor data array. See BeBook entry for BCursor for details @@ -112,6 +106,7 @@ ServerCursor::ServerCursor(const int8* data) } } + /*! \brief Constructor \param data Pointer to bitmap data in memory, the padding bytes should be contained when format less than 32 bpp. @@ -128,6 +123,7 @@ ServerCursor::ServerCursor(const uint8* alreadyPaddedData, memcpy(Bits(), alreadyPaddedData, BitsLength()); } + /*! \brief Copy constructor \param cursor cursor to copy @@ -149,12 +145,14 @@ ServerCursor::ServerCursor(const ServerCursor* cursor) } } + //! Frees the heap space allocated for the cursor's image data ServerCursor::~ServerCursor() { _FreeBuffer(); } + /*! \brief Sets the cursor's hotspot \param pt New location of hotspot, constrained to the cursor's boundaries. @@ -166,9 +164,3 @@ ServerCursor::SetHotSpot(BPoint pt) fHotSpot.ConstrainTo(Bounds()); } -// SetAppSignature -void -ServerCursor::SetAppSignature(const char* signature) -{ - fAppSignature.SetTo((signature) ? signature : ""); -} diff --git a/src/servers/app/ServerWindow.cpp b/src/servers/app/ServerWindow.cpp index 3b21221777..2cb0081fb0 100644 --- a/src/servers/app/ServerWindow.cpp +++ b/src/servers/app/ServerWindow.cpp @@ -1243,16 +1243,16 @@ ServerWindow::_DispatchViewMessage(int32 code, fCurrentLayer->SetResizeMode(resizeMode); break; } - case AS_LAYER_CURSOR: + case AS_LAYER_SET_CURSOR: { DTRACE(("ServerWindow %s: Message AS_LAYER_CURSOR: ViewLayer: %s - NOT IMPLEMENTED\n", Title(), fCurrentLayer->Name())); - int32 token = -1; - link.Read(&token); + int32 token; + if (link.Read(&token) == B_OK) { + // TODO: this badly needs reference counting + ServerCursor* cursor = fDesktop->GetCursorManager().FindCursor(token); + fCurrentLayer->SetCursor(cursor); + } - // TODO: this badly needs reference counting - ServerCursor* cursor = fDesktop->GetCursorManager().FindCursor(token); - fCurrentLayer->SetCursor(cursor); - // TODO: if fCurrentLayer is the view under the cursor, the appearance should change immediately! break; } diff --git a/src/servers/app/WindowLayer.cpp b/src/servers/app/WindowLayer.cpp index 248034f524..7a5b610591 100644 --- a/src/servers/app/WindowLayer.cpp +++ b/src/servers/app/WindowLayer.cpp @@ -988,13 +988,15 @@ WindowLayer::MouseMoved(BMessage *msg, BPoint where, int32* _viewToken, // 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 != currentCursor) { -// TODO: custom cursors cannot be drawn by the HWInterface right now (wrong bitmap format) -// fDesktop->HWInterface()->SetCursor(cursor); - } + if (cursor == NULL) + cursor = fDesktop->GetCursorManager().GetCursor(B_CURSOR_DEFAULT); + + if (cursor != currentCursor && cursor != NULL) + fDesktop->HWInterface()->SetCursor(cursor); } } diff --git a/src/servers/app/drawing/HWInterface.cpp b/src/servers/app/drawing/HWInterface.cpp index d70f84a8a1..d05c17a0c3 100644 --- a/src/servers/app/drawing/HWInterface.cpp +++ b/src/servers/app/drawing/HWInterface.cpp @@ -40,8 +40,11 @@ HWInterface::HWInterface(bool doubleBuffered) HWInterface::~HWInterface() { delete fCursorAreaBackup; - delete fCursor; - delete fCursorAndDragBitmap; + + // The standard cursor doesn't belong us - the drag bitmap might + if (fCursor != fCursorAndDragBitmap) + delete fCursorAndDragBitmap; + delete fUpdateExecutor; } @@ -81,17 +84,24 @@ HWInterface::SetCursor(ServerCursor* cursor) // considered iritating to the user to // change cursor shapes while something // is dragged anyways. + // TODO: like a "+" or "-" sign when dragging some files to indicate + // the current drag mode? WriteUnlock(); return; } if (fCursor != cursor) { BRect oldFrame = _CursorFrame(); - delete fCursor; + + if (fCursorAndDragBitmap == fCursor) { + // make sure _AdoptDragBitmap doesn't delete a real cursor + fCursorAndDragBitmap = NULL; + } + fCursor = cursor; Invalidate(oldFrame); - BRect r = _CursorFrame(); + _AdoptDragBitmap(fDragBitmap, fDragBitmapOffset); - Invalidate(r); + Invalidate(_CursorFrame()); } WriteUnlock(); }