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
This commit is contained in:
Axel Dörfler
2006-02-05 18:14:14 +00:00
parent 73b3ea3cd7
commit aa1f543799
18 changed files with 333 additions and 482 deletions
+22 -64
View File
@@ -1,82 +1,40 @@
//------------------------------------------------------------------------------ /*
// Copyright (c) 2001-2002, OpenBeOS * Copyright 2006, Haiku, Inc. All Rights Reserved.
// * Distributed under the terms of the MIT License.
// 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 ([email protected])
// Description: BCursor describes a view-wide or application-wide cursor.
//------------------------------------------------------------------------------
#ifndef _CURSOR_H #ifndef _CURSOR_H
#define _CURSOR_H #define _CURSOR_H
// Standard Includes -----------------------------------------------------------
// System Includes -------------------------------------------------------------
#include <Archivable.h> #include <Archivable.h>
#include <BeBuild.h>
#include <InterfaceDefs.h> #include <InterfaceDefs.h>
// Project Includes ------------------------------------------------------------
// Local Includes --------------------------------------------------------------
// Local Defines ---------------------------------------------------------------
// Globals ---------------------------------------------------------------------
// BCursor class ---------------------------------------------------------------
class BCursor : BArchivable { class BCursor : BArchivable {
public: public:
BCursor(const void* cursorData); BCursor(const void* cursorData);
BCursor(BMessage* data); BCursor(BMessage* data);
virtual ~BCursor(); virtual ~BCursor();
virtual status_t Archive(BMessage* into, bool deep = true) const; virtual status_t Archive(BMessage* archive, bool deep = true) const;
static BArchivable* Instantiate(BMessage* data); static BArchivable* Instantiate(BMessage* archive);
// Private or reserved --------------------------------------------------------- private:
virtual status_t Perform(perform_code d, void* arg); 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(); private:
virtual void _ReservedCursor2(); friend class BApplication;
virtual void _ReservedCursor3(); friend class BView;
virtual void _ReservedCursor4();
friend class BApplication; int32 fServerToken;
friend class BView; bool fNeedToFree;
int32 m_serverToken; uint32 _reserved[6];
int32 m_needToFree;
uint32 _reserved[6];
}; };
//------------------------------------------------------------------------------
#endif // _CURSOR_H #endif // _CURSOR_H
/*
* $Log $
*
* $Id $
*
*/
+10 -18
View File
@@ -1,13 +1,14 @@
/* /*
* 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:
* DarkWyrm <[email protected]> * DarkWyrm <[email protected]>
* Jérôme Duval, [email protected] * Jérôme Duval, [email protected]
* Axel Dörfler, [email protected]
*/ */
#ifndef _APP_SERVER_PROTOCOL_H_ #ifndef APP_SERVER_PROTOCOL_H
#define _APP_SERVER_PROTOCOL_H_ #define APP_SERVER_PROTOCOL_H
#include <SupportDefs.h> #include <SupportDefs.h>
@@ -54,25 +55,16 @@ enum {
AS_RELEASE_SERVERMEM, AS_RELEASE_SERVERMEM,
AS_AREA_MESSAGE, AS_AREA_MESSAGE,
// Cursor definitions // Cursor commands
AS_SET_CURSOR_DATA, AS_SET_CURSOR,
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,
AS_SHOW_CURSOR, AS_SHOW_CURSOR,
AS_HIDE_CURSOR, AS_HIDE_CURSOR,
AS_OBSCURE_CURSOR, AS_OBSCURE_CURSOR,
AS_QUERY_CURSOR_HIDDEN, AS_QUERY_CURSOR_HIDDEN,
AS_CREATE_BCURSOR, AS_CREATE_CURSOR,
AS_DELETE_BCURSOR, AS_DELETE_CURSOR,
AS_BEGIN_RECT_TRACKING, AS_BEGIN_RECT_TRACKING,
AS_END_RECT_TRACKING, AS_END_RECT_TRACKING,
@@ -260,7 +252,7 @@ enum {
AS_LAYER_SET_ORIGIN, AS_LAYER_SET_ORIGIN,
AS_LAYER_GET_ORIGIN, AS_LAYER_GET_ORIGIN,
AS_LAYER_RESIZE_MODE, AS_LAYER_RESIZE_MODE,
AS_LAYER_CURSOR, AS_LAYER_SET_CURSOR,
AS_LAYER_BEGIN_RECT_TRACK, AS_LAYER_BEGIN_RECT_TRACK,
AS_LAYER_END_RECT_TRACK, AS_LAYER_END_RECT_TRACK,
AS_LAYER_DRAG_RECT, AS_LAYER_DRAG_RECT,
@@ -320,4 +312,4 @@ enum {
AS_LAST_CODE AS_LAST_CODE
}; };
#endif // _APP_SERVER_PROTOCOL_H_ #endif // APP_SERVER_PROTOCOL_H
+21 -36
View File
@@ -1,39 +1,21 @@
//------------------------------------------------------------------------------ /*
// Copyright (c) 2001-2005, Haiku * Copyright 2001-2006, Haiku.
// * Distributed under the terms of the MIT License.
// Permission is hereby granted, free of charge, to any person obtaining a *
// copy of this software and associated documentation files (the "Software"), * Authors:
// to deal in the Software without restriction, including without limitation * DarkWyrm <[email protected]>
// the rights to use, copy, modify, merge, publish, distribute, sublicense, */
// and/or sell copies of the Software, and to permit persons to whom the #ifndef CURSOR_SET_H
// Software is furnished to do so, subject to the following conditions: #define CURSOR_SET_H
//
// 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 <[email protected]>
// Description: Private file encapsulating of the Haiku system cursor API
//
//------------------------------------------------------------------------------
#ifndef CURSORSET_H_
#define CURSORSET_H_
#include <Bitmap.h> #include <Bitmap.h>
#include <Cursor.h> #include <Cursor.h>
#include <Message.h> #include <Message.h>
typedef enum
{ typedef enum {
B_CURSOR_DEFAULT=0, B_CURSOR_DEFAULT = 1,
B_CURSOR_TEXT, B_CURSOR_TEXT,
B_CURSOR_MOVE, B_CURSOR_MOVE,
B_CURSOR_DRAG, B_CURSOR_DRAG,
@@ -49,15 +31,14 @@ typedef enum
class ServerCursor; class ServerCursor;
const char *CursorWhichToString(cursor_which which);
BBitmap *CursorDataToBitmap(int8 *data);
/*! /*!
\brief Class to manage system cursor sets \brief Class to manage system cursor sets
*/ */
class CursorSet : public BMessage { class CursorSet : public BMessage {
public: public:
CursorSet(const char *name); CursorSet(const char *name);
status_t Save(const char *path,int32 saveflags=0); status_t Save(const char *path,int32 saveflags=0);
status_t Load(const char *path); status_t Load(const char *path);
status_t AddCursor(cursor_which which,const BBitmap *cursor, const BPoint &hotspot); 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); status_t FindCursor(cursor_which which, ServerCursor **cursor);
void SetName(const char *name); void SetName(const char *name);
const char *GetName(void); const char *GetName(void);
private:
const char *_CursorWhichToString(cursor_which which);
BBitmap *_CursorDataToBitmap(int8 *data);
}; };
#endif #endif // CURSOR_SET_H
+13 -28
View File
@@ -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:
@@ -26,51 +26,34 @@ class BitmapManager;
*/ */
class ServerBitmap { class ServerBitmap {
public: public:
inline bool IsValid() const
{ return fInitialized; }
void Acquire(); 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 inline area_id Area() const
{ return fArea; } { return fArea; }
// Returns the offset of the bitmap in its area
inline int32 AreaOffset() const inline int32 AreaOffset() const
{ return fOffset; } { return fOffset; }
//! Returns the bitmap's buffer
inline uint8* Bits() const inline uint8* Bits() const
{ return fBuffer; } { return fBuffer; }
inline uint32 BitsLength() const inline uint32 BitsLength() const
{ return (uint32)(fBytesPerRow * fHeight); } { return (uint32)(fBytesPerRow * fHeight); }
inline BRect Bounds() const inline BRect Bounds() const
{ return BRect(0, 0, fWidth - 1, fHeight - 1); } { 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 inline int32 Width() const
{ return fWidth; } { return fWidth; }
//! Returns the bitmap's row count
inline int32 Height() const inline int32 Height() const
{ return fHeight; } { return fHeight; }
inline bool IsValid() const inline int32 BytesPerRow() const
{ return fInitialized; } { return fBytesPerRow; }
inline uint8 BitsPerPixel() const
{ return fBitsPerPixel; }
inline color_space ColorSpace() const
{ return fSpace; }
//! Returns the identifier token for the bitmap //! Returns the identifier token for the bitmap
inline int32 Token() const inline int32 Token() const
@@ -79,6 +62,8 @@ class ServerBitmap {
//! Does a shallow copy of the bitmap passed to it //! Does a shallow copy of the bitmap passed to it
inline void ShallowCopy(const ServerBitmap *from); inline void ShallowCopy(const ServerBitmap *from);
void PrintToStream();
protected: protected:
friend class BitmapManager; friend class BitmapManager;
friend class PicturePlayer; friend class PicturePlayer;
@@ -86,7 +71,7 @@ protected:
ServerBitmap(BRect rect, ServerBitmap(BRect rect,
color_space space, color_space space,
int32 flags, int32 flags,
int32 bytesperline = -1, int32 bytesPerRow = -1,
screen_id screen = B_MAIN_SCREEN_ID); screen_id screen = B_MAIN_SCREEN_ID);
ServerBitmap(const ServerBitmap* bmp); ServerBitmap(const ServerBitmap* bmp);
virtual ~ServerBitmap(); virtual ~ServerBitmap();
+18 -49
View File
@@ -1,50 +1,25 @@
//------------------------------------------------------------------------------ /*
// Copyright (c) 2001-2002, Haiku, Inc. * Copyright 2001-2006, Haiku.
// * Distributed under the terms of the MIT License.
// Permission is hereby granted, free of charge, to any person obtaining a *
// copy of this software and associated documentation files (the "Software"), * Authors:
// to deal in the Software without restriction, including without limitation * DarkWyrm <[email protected]>
// the rights to use, copy, modify, merge, publish, distribute, sublicense, * Stephan Aßmus <[email protected]>
// and/or sell copies of the Software, and to permit persons to whom the * Axel Dörfler, [email protected]e
// Software is furnished to do so, subject to the following conditions: */
// #ifndef SERVER_CURSOR_H
// The above copyright notice and this permission notice shall be included in #define SERVER_CURSOR_H
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR #include "ServerBitmap.h"
// 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 <[email protected]>
// Stephan Aßmus <[email protected]>
// Description: Glorified ServerBitmap used for cursor work.
//
//------------------------------------------------------------------------------
#ifndef SERVERCURSOR_H_
#define SERVERCURSOR_H_
#include <Point.h> #include <Point.h>
#include <String.h> #include <String.h>
#include "ServerBitmap.h"
class ServerApp; class ServerApp;
class CursorManager; 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 { class ServerCursor : public ServerBitmap {
public: public:
ServerCursor(BRect r, color_space space, ServerCursor(BRect r, color_space space,
@@ -64,24 +39,18 @@ class ServerCursor : public ServerBitmap {
BPoint GetHotSpot() const BPoint GetHotSpot() const
{ return fHotSpot; } { return fHotSpot; }
void SetAppSignature(const char* signature);
const char* GetAppSignature() const
{ return fAppSignature.String(); }
void SetOwningTeam(team_id tid) void SetOwningTeam(team_id tid)
{ fOwningTeam = tid; } { fOwningTeam = tid; }
team_id OwningTeam() const team_id OwningTeam() const
{ return fOwningTeam; } { return fOwningTeam; }
//! Returns the cursor's ID int32 Token() const
int32 ID() const
{ return fToken; } { return fToken; }
private: private:
friend class CursorManager; friend class CursorManager;
BPoint fHotSpot; BPoint fHotSpot;
team_id fOwningTeam; team_id fOwningTeam;
BString fAppSignature;
}; };
#endif // SERVERCURSOR_H_ #endif // SERVER_CURSOR_H
+12 -22
View File
@@ -666,13 +666,11 @@ BApplication::IsCursorHidden() const
void void
BApplication::SetCursor(const void *cursor) BApplication::SetCursor(const void *cursorData)
{ {
// BeBook sez: If you want to call SetCursor() without forcing an immediate BCursor cursor(cursorData);
// sync of the Application Server, you have to use a BCursor. SetCursor(&cursor, true);
// By deductive reasoning, this function forces a sync. =) // forces the cursor to be sync'ed
BCursor Cursor(cursor);
SetCursor(&Cursor, true);
} }
@@ -680,14 +678,14 @@ void
BApplication::SetCursor(const BCursor *cursor, bool sync) BApplication::SetCursor(const BCursor *cursor, bool sync)
{ {
BPrivate::AppServerLink link; BPrivate::AppServerLink link;
int32 code = SERVER_FALSE; link.StartMessage(AS_SET_CURSOR);
link.StartMessage(AS_SET_CURSOR_BCURSOR);
link.Attach<bool>(sync); link.Attach<bool>(sync);
link.Attach<int32>(cursor->m_serverToken); link.Attach<int32>(cursor->fServerToken);
if (sync)
if (sync) {
int32 code;
link.FlushWithReply(code); link.FlushWithReply(code);
else } else
link.Flush(); link.Flush();
} }
@@ -695,24 +693,16 @@ BApplication::SetCursor(const BCursor *cursor, bool sync)
int32 int32
BApplication::CountWindows() const 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); return count_windows(false);
// we're ignoring menu windows
} }
BWindow * BWindow *
BApplication::WindowAt(int32 index) const 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); return window_at(index, false);
// we're ignoring menu windows
} }
+40 -27
View File
@@ -1,10 +1,11 @@
/* /*
* 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:
* Frans van Nispen (xlr8@tref.nl) * Frans van Nispen (xlr8@tref.nl)
* Gabe Yoder (gyoder@stny.rr.com) * Gabe Yoder (gyoder@stny.rr.com)
* Axel Dörfler, axeld@pinc-software.de
*/ */
/** BCursor describes a view-wide or application-wide cursor. */ /** BCursor describes a view-wide or application-wide cursor. */
@@ -15,8 +16,9 @@
*/ */
#include <AppDefs.h> #include <AppDefs.h>
#include <Cursor.h> #include <Cursor.h>
#include <CursorSet.h>
#include <AppServerLink.h> #include <AppServerLink.h>
#include <ServerProtocol.h> #include <ServerProtocol.h>
@@ -27,9 +29,20 @@ const BCursor *B_CURSOR_I_BEAM;
BCursor::BCursor(const void *cursorData) BCursor::BCursor(const void *cursorData)
:
fServerToken(-1),
fNeedToFree(false)
{ {
int8 *data = (int8 *)cursorData; const uint8 *data = (const uint8 *)cursorData;
m_serverToken = 0;
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 if (data == NULL
|| data[0] != 16 // size || data[0] != 16 // size
@@ -38,47 +51,50 @@ BCursor::BCursor(const void *cursorData)
return; return;
// Send data directly to server // Send data directly to server
BPrivate::AppServerLink serverlink; BPrivate::AppServerLink link;
int32 code = SERVER_FALSE; link.StartMessage(AS_CREATE_CURSOR);
link.Attach(cursorData, 68);
serverlink.StartMessage(AS_CREATE_BCURSOR); status_t status;
serverlink.Attach(cursorData, 68); if (link.FlushWithReply(status) == B_OK && status == B_OK) {
serverlink.FlushWithReply(code); link.Read<int32>(&fServerToken);
if (code == SERVER_TRUE) fNeedToFree = true;
serverlink.Read<int32>(&m_serverToken); }
} }
// undefined on BeOS
BCursor::BCursor(BMessage *data) BCursor::BCursor(BMessage *data)
{ {
m_serverToken = 0; // undefined on BeOS
fServerToken = -1;
fNeedToFree = false;
} }
BCursor::~BCursor() BCursor::~BCursor()
{ {
// Notify server to deallocate server-side objects for this cursor // Notify server to deallocate server-side objects for this cursor
BPrivate::AppServerLink serverlink; if (fNeedToFree) {
serverlink.StartMessage(AS_DELETE_BCURSOR); BPrivate::AppServerLink link;
serverlink.Attach<int32>(m_serverToken); link.StartMessage(AS_DELETE_CURSOR);
serverlink.Flush(); link.Attach<int32>(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; return B_OK;
} }
// not implemented on BeOS BArchivable *
BCursor::Instantiate(BMessage *data)
BArchivable *BCursor::Instantiate(BMessage *data)
{ {
// not implemented on BeOS
return NULL; return NULL;
} }
@@ -86,9 +102,6 @@ BArchivable *BCursor::Instantiate(BMessage *data)
status_t status_t
BCursor::Perform(perform_code d, void *arg) BCursor::Perform(perform_code d, void *arg)
{ {
/*
printf("perform %d\n", (int)d);
*/
return B_OK; return B_OK;
} }
+1
View File
@@ -19,6 +19,7 @@ if $(RUN_WITHOUT_APP_SERVER) != 0 {
UsePrivateHeaders shared app interface ; UsePrivateHeaders shared app interface ;
UsePrivateHeaders [ FDirName kernel util ] ; # For KMessage.h UsePrivateHeaders [ FDirName kernel util ] ; # For KMessage.h
UsePrivateHeaders [ FDirName servers app ] ;
SetSubDirSupportedPlatforms haiku libbe_test ; SetSubDirSupportedPlatforms haiku libbe_test ;
+2 -2
View File
@@ -1004,8 +1004,8 @@ BView::SetViewCursor(const BCursor *cursor, bool sync)
check_lock(); check_lock();
fOwner->fLink->StartMessage(AS_LAYER_CURSOR); fOwner->fLink->StartMessage(AS_LAYER_SET_CURSOR);
fOwner->fLink->Attach<int32>(cursor->m_serverToken); fOwner->fLink->Attach<int32>(cursor->fServerToken);
if (sync) if (sync)
fOwner->fLink->Flush(); fOwner->fLink->Flush();
+51 -73
View File
@@ -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:
@@ -9,9 +9,6 @@
/** Handles the system's cursor infrastructure */ /** Handles the system's cursor infrastructure */
#include <Directory.h>
#include <String.h>
#include "CursorData.h" #include "CursorData.h"
#include "CursorManager.h" #include "CursorManager.h"
#include "HaikuSystemCursor.h" #include "HaikuSystemCursor.h"
@@ -19,10 +16,13 @@
#include "ServerConfig.h" #include "ServerConfig.h"
#include "ServerTokenSpace.h" #include "ServerTokenSpace.h"
#include <Autolock.h>
#include <Directory.h>
#include <String.h>
//! Initializes the CursorManager
CursorManager::CursorManager() CursorManager::CursorManager()
: BLocker("CursorManager") : BLocker("CursorManager")
{ {
// Set system cursors to "unassigned" // Set system cursors to "unassigned"
// ToDo: decide about default cursor // ToDo: decide about default cursor
@@ -34,11 +34,11 @@ CursorManager::CursorManager()
fDefaultCursor->SetHotSpot(BPoint(1, 0)); fDefaultCursor->SetHotSpot(BPoint(1, 0));
#else #else
fDefaultCursor = new ServerCursor(default_cursor_data); fDefaultCursor = new ServerCursor(default_cursor_data);
AddCursor(fDefaultCursor);
#endif #endif
AddCursor(fDefaultCursor, B_CURSOR_DEFAULT);
fTextCursor = new ServerCursor(default_text_data); fTextCursor = new ServerCursor(default_text_data);
AddCursor(fTextCursor); AddCursor(fTextCursor, B_CURSOR_TEXT);
fMoveCursor = new ServerCursor(default_move_data); fMoveCursor = new ServerCursor(default_move_data);
AddCursor(fMoveCursor); AddCursor(fMoveCursor);
@@ -67,16 +67,8 @@ CursorManager::CursorManager()
CursorManager::~CursorManager() CursorManager::~CursorManager()
{ {
for (int32 i = 0; i < fCursorList.CountItems(); i++) { for (int32 i = 0; i < fCursorList.CountItems(); i++) {
ServerCursor *cursor = (ServerCursor *)fCursorList.ItemAt(i); delete (ServerCursor *)fCursorList.ItemAt(i);
if (cursor)
delete cursor;
} }
// 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 \return The token assigned to the cursor or B_ERROR if sc is NULL
*/ */
int32 int32
CursorManager::AddCursor(ServerCursor* cursor) CursorManager::AddCursor(ServerCursor* cursor, int32 token)
{ {
if (!cursor) if (!cursor)
return B_ERROR; return B_ERROR;
@@ -94,17 +86,32 @@ CursorManager::AddCursor(ServerCursor* cursor)
Lock(); Lock();
fCursorList.AddItem(cursor); fCursorList.AddItem(cursor);
int32 token = fTokenSpace.NewToken(B_SERVER_TOKEN, cursor); if (token == -1)
cursor->fToken = token; cursor->fToken = fTokenSpace.NewToken(kCursorToken, cursor);
else {
fTokenSpace.SetToken(token, kCursorToken, cursor);
cursor->fToken = token;
}
Unlock(); Unlock();
return token; 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 \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 If the cursor is not found, this call does nothing
*/ */
@@ -113,11 +120,11 @@ CursorManager::DeleteCursor(int32 token)
{ {
Lock(); Lock();
for (int32 i = 0; i < fCursorList.CountItems(); i++) { for (int32 index = 0; index < fCursorList.CountItems(); index++) {
ServerCursor *cursor = (ServerCursor *)fCursorList.ItemAt(i); ServerCursor *cursor = (ServerCursor *)fCursorList.ItemAt(index);
if (cursor && cursor->fToken == token) { if (cursor && cursor->fToken == token) {
fCursorList.RemoveItem(i); _RemoveCursor(index);
delete cursor; delete cursor;
break; break;
} }
@@ -132,21 +139,17 @@ CursorManager::DeleteCursor(int32 token)
\param signature Signature to which the cursors belong \param signature Signature to which the cursors belong
*/ */
void void
CursorManager::RemoveAppCursors(team_id team) CursorManager::DeleteCursors(team_id team)
{ {
Lock(); Lock();
int32 index = 0; for (int32 index = fCursorList.CountItems(); index-- > 0;) {
while (index < fCursorList.CountItems()) {
ServerCursor *cursor = (ServerCursor *)fCursorList.ItemAt(index); ServerCursor *cursor = (ServerCursor *)fCursorList.ItemAt(index);
if (!cursor) if (cursor->OwningTeam() != team)
break; continue;
if (cursor->OwningTeam() == team) { _RemoveCursor(index);
fCursorList.RemoveItem(index); delete cursor;
delete cursor;
} else
index++;
} }
Unlock(); Unlock();
@@ -165,7 +168,8 @@ CursorManager::RemoveAppCursors(team_id team)
void void
CursorManager::SetCursorSet(const char *path) CursorManager::SetCursorSet(const char *path)
{ {
Lock(); BAutolock locker (this);
CursorSet cursorSet(NULL); CursorSet cursorSet(NULL);
if (!path || cursorSet.Load(path) != B_OK) if (!path || cursorSet.Load(path) != B_OK)
@@ -226,8 +230,6 @@ CursorManager::SetCursorSet(const char *path)
delete fEWCursor; delete fEWCursor;
fEWCursor = cursor; fEWCursor = cursor;
} }
Unlock();
} }
@@ -240,52 +242,31 @@ CursorManager::SetCursorSet(const char *path)
ServerCursor * ServerCursor *
CursorManager::GetCursor(cursor_which which) CursorManager::GetCursor(cursor_which which)
{ {
ServerCursor *cursor = NULL; BAutolock locker(this);
Lock();
switch (which) { switch (which) {
case B_CURSOR_DEFAULT: case B_CURSOR_DEFAULT:
cursor = fDefaultCursor; return fDefaultCursor;
break;
case B_CURSOR_TEXT: case B_CURSOR_TEXT:
cursor = fTextCursor; return fTextCursor;
break;
case B_CURSOR_MOVE: case B_CURSOR_MOVE:
cursor = fMoveCursor; return fMoveCursor;
break;
case B_CURSOR_DRAG: case B_CURSOR_DRAG:
cursor = fDragCursor; return fDragCursor;
break;
case B_CURSOR_RESIZE: case B_CURSOR_RESIZE:
cursor = fResizeCursor; return fResizeCursor;
break;
case B_CURSOR_RESIZE_NWSE: case B_CURSOR_RESIZE_NWSE:
cursor = fNWSECursor; return fNWSECursor;
break;
case B_CURSOR_RESIZE_NESW: case B_CURSOR_RESIZE_NESW:
cursor = fNESWCursor; return fNESWCursor;
break;
case B_CURSOR_RESIZE_NS: case B_CURSOR_RESIZE_NS:
cursor = fNSCursor; return fNSCursor;
break;
case B_CURSOR_RESIZE_EW: case B_CURSOR_RESIZE_EW:
cursor = fEWCursor; return fEWCursor;
break;
default: default:
break; return NULL;
} }
Unlock();
return cursor;
} }
@@ -382,9 +363,6 @@ CursorManager::ChangeCursor(cursor_which which, int32 token)
return; return;
} }
if (cursor->GetAppSignature())
cursor->SetAppSignature("");
fCursorList.RemoveItem(cursor); fCursorList.RemoveItem(cursor);
Unlock(); Unlock();
} }
@@ -399,7 +377,7 @@ ServerCursor *
CursorManager::FindCursor(int32 token) CursorManager::FindCursor(int32 token)
{ {
ServerCursor* cursor; ServerCursor* cursor;
if (gTokenSpace.GetToken(token, kCursorToken, (void**)&cursor) == B_OK) if (fTokenSpace.GetToken(token, kCursorToken, (void**)&cursor) == B_OK)
return cursor; return cursor;
return NULL; return NULL;
+5 -3
View File
@@ -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:
@@ -33,9 +33,9 @@ class CursorManager : public BLocker {
CursorManager(); CursorManager();
virtual ~CursorManager(); virtual ~CursorManager();
int32 AddCursor(ServerCursor* cursor); int32 AddCursor(ServerCursor* cursor, int32 token = -1);
void DeleteCursor(int32 token); void DeleteCursor(int32 token);
void RemoveAppCursors(team_id team); void DeleteCursors(team_id team);
void SetCursorSet(const char* path); void SetCursorSet(const char* path);
ServerCursor* GetCursor(cursor_which which); ServerCursor* GetCursor(cursor_which which);
@@ -45,6 +45,8 @@ class CursorManager : public BLocker {
ServerCursor* FindCursor(int32 token); ServerCursor* FindCursor(int32 token);
private: private:
ServerCursor* _RemoveCursor(int32 index);
BList fCursorList; BList fCursorList;
BTokenSpace fTokenSpace; BTokenSpace fTokenSpace;
+32 -39
View File
@@ -1,37 +1,21 @@
//------------------------------------------------------------------------------ /*
// Copyright (c) 2001-2005, Haiku, Inc. * Copyright 2001-2006, Haiku.
// * Distributed under the terms of the MIT License.
// Permission is hereby granted, free of charge, to any person obtaining a *
// copy of this software and associated documentation files (the "Software"), * Authors:
// to deal in the Software without restriction, including without limitation * DarkWyrm <bpmagic@columbus.rr.com>
// 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 <[email protected]>
// Description: Private file encapsulating OBOS system cursor API
//
//------------------------------------------------------------------------------
#include <PortLink.h>
#include <AppServerLink.h> #include <AppServerLink.h>
#include <CursorSet.h>
#include <PortLink.h>
#include <ServerCursor.h>
#include <ServerProtocol.h> #include <ServerProtocol.h>
#include <OS.h> #include <OS.h>
#include <String.h> #include <String.h>
#include <File.h> #include <File.h>
#include "CursorSet.h"
#include "ServerCursor.h"
/*! /*!
@@ -44,6 +28,7 @@ CursorSet::CursorSet(const char *name)
AddString("name", name ? name : "Untitled"); AddString("name", name ? name : "Untitled");
} }
/*! /*!
\brief Saves the data in the cursor set to a file \brief Saves the data in the cursor set to a file
\param path Path of the file to save to. \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 - \c other value: See BFile::SetTo and BMessage::Flatten return codes
*/ */
status_t status_t
CursorSet::Save(const char *path, int32 saveflags) CursorSet::Save(const char *path, int32 saveFlags)
{ {
if (!path) if (!path)
return B_BAD_VALUE; return B_BAD_VALUE;
BFile file; 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) if (status != B_OK)
return status; return status;
return Flatten(&file); return Flatten(&file);
} }
/*! /*!
\brief Loads the data into the cursor set from a file \brief Loads the data into the cursor set from a file
\param path Path of the file to load from. \param path Path of the file to load from.
@@ -89,6 +75,7 @@ CursorSet::Load(const char *path)
return Unflatten(&file); return Unflatten(&file);
} }
/*! /*!
\brief Adds the cursor to the set and replaces any existing entry for the given specifier \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 \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; return B_BAD_VALUE;
// Remove the data if it exists already // Remove the data if it exists already
RemoveData(CursorWhichToString(which)); RemoveData(_CursorWhichToString(which));
// Actually add the data to our set // Actually add the data to our set
BMessage msg((int32)which); 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.AddInt32("_rowbytes",cursor->BytesPerRow());
msg.AddPoint("hotspot",hotspot); msg.AddPoint("hotspot",hotspot);
msg.AddData("_data",B_RAW_TYPE,cursor->Bits(), cursor->BitsLength()); msg.AddData("_data",B_RAW_TYPE,cursor->Bits(), cursor->BitsLength());
AddMessage(CursorWhichToString(which),&msg); AddMessage(_CursorWhichToString(which),&msg);
return B_OK; return B_OK;
} }
/*! /*!
\brief Adds the cursor to the set and replaces any existing entry for the given specifier \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 \param which System cursor specifier defined in CursorSet.h
@@ -138,7 +126,7 @@ CursorSet::AddCursor(cursor_which which, int8 *data)
if (!data) if (!data)
return B_BAD_VALUE; return B_BAD_VALUE;
BBitmap *bmp = CursorDataToBitmap(data); BBitmap *bmp = _CursorDataToBitmap(data);
BPoint pt(data[2],data[3]); BPoint pt(data[2],data[3]);
status_t stat = AddCursor(which,bmp,pt); status_t stat = AddCursor(which,bmp,pt);
@@ -147,6 +135,7 @@ CursorSet::AddCursor(cursor_which which, int8 *data)
return stat; return stat;
} }
/*! /*!
\brief Removes the data associated with the specifier from the cursor set \brief Removes the data associated with the specifier from the cursor set
\param which System cursor specifier defined in CursorSet.h \param which System cursor specifier defined in CursorSet.h
@@ -154,9 +143,10 @@ CursorSet::AddCursor(cursor_which which, int8 *data)
void void
CursorSet::RemoveCursor(cursor_which which) CursorSet::RemoveCursor(cursor_which which)
{ {
RemoveData(CursorWhichToString(which)); RemoveData(_CursorWhichToString(which));
} }
/*! /*!
\brief Retrieves a cursor from the set. \brief Retrieves a cursor from the set.
\param which System cursor specifier defined in CursorSet.h \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; return B_BAD_VALUE;
BMessage msg; BMessage msg;
if (FindMessage(CursorWhichToString(which), &msg) != B_OK) if (FindMessage(_CursorWhichToString(which), &msg) != B_OK)
return B_NAME_NOT_FOUND; return B_NAME_NOT_FOUND;
const void *buffer; const void *buffer;
@@ -206,6 +196,7 @@ CursorSet::FindCursor(cursor_which which, BBitmap **cursor, BPoint *hotspot)
return B_ERROR; return B_ERROR;
} }
/*! /*!
\brief Retrieves a cursor from the set. \brief Retrieves a cursor from the set.
\param which System cursor specifier defined in CursorSet.h \param which System cursor specifier defined in CursorSet.h
@@ -222,7 +213,7 @@ status_t
CursorSet::FindCursor(cursor_which which, ServerCursor **_cursor) CursorSet::FindCursor(cursor_which which, ServerCursor **_cursor)
{ {
BMessage msg; BMessage msg;
if (FindMessage(CursorWhichToString(which), &msg) != B_OK) if (FindMessage(_CursorWhichToString(which), &msg) != B_OK)
return B_NAME_NOT_FOUND; return B_NAME_NOT_FOUND;
const char *className; const char *className;
@@ -250,6 +241,7 @@ CursorSet::FindCursor(cursor_which which, ServerCursor **_cursor)
return B_ERROR; return B_ERROR;
} }
/*! /*!
\brief Returns the name of the set \brief Returns the name of the set
\return The name of the set \return The name of the set
@@ -264,6 +256,7 @@ CursorSet::GetName(void)
return NULL; return NULL;
} }
/*! /*!
\brief Renames the cursor set \brief Renames the cursor set
\param name new name of the set. \param name new name of the set.
@@ -287,7 +280,7 @@ CursorSet::SetName(const char *name)
\return Name for the cursor specifier \return Name for the cursor specifier
*/ */
const char * const char *
CursorWhichToString(cursor_which which) CursorSet::_CursorWhichToString(cursor_which which)
{ {
switch (which) { switch (which) {
case B_CURSOR_DEFAULT: case B_CURSOR_DEFAULT:
@@ -323,7 +316,7 @@ CursorWhichToString(cursor_which which)
BBitmaps returned by this function are always in the RGBA32 color space BBitmaps returned by this function are always in the RGBA32 color space
*/ */
BBitmap * BBitmap *
CursorDataToBitmap(int8 *data) CursorSet::_CursorDataToBitmap(int8 *data)
{ {
// 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
+41 -69
View File
@@ -118,14 +118,6 @@ ServerApp::ServerApp(Desktop* desktop, port_id clientReplyPort,
BMessenger::Private(fHandlerMessenger).SetTo(fClientTeam, BMessenger::Private(fHandlerMessenger).SetTo(fClientTeam,
clientLooperPort, clientToken); clientLooperPort, clientToken);
ServerCursor *defaultCursor =
fDesktop->GetCursorManager().GetCursor(B_CURSOR_DEFAULT);
if (defaultCursor) {
fAppCursor = new ServerCursor(defaultCursor);
fAppCursor->SetOwningTeam(fClientTeam);
}
fInitialWorkspace = desktop->CurrentWorkspace(); fInitialWorkspace = desktop->CurrentWorkspace();
// TODO: this should probably be retrieved when the app is loaded! // TODO: this should probably be retrieved when the app is loaded!
@@ -191,7 +183,7 @@ ServerApp::~ServerApp()
delete (ServerPicture*)fPictureList.ItemAtFast(i); delete (ServerPicture*)fPictureList.ItemAtFast(i);
} }
fDesktop->GetCursorManager().RemoveAppCursors(fClientTeam); fDesktop->GetCursorManager().DeleteCursors(fClientTeam);
STRACE(("ServerApp %s::~ServerApp(): Exiting\n", Signature())); STRACE(("ServerApp %s::~ServerApp(): Exiting\n", Signature()));
} }
@@ -298,9 +290,8 @@ ServerApp::Activate(bool value)
void void
ServerApp::SetCursor() ServerApp::SetCursor()
{ {
// TODO: custom cursors cannot be drawn by the HWInterface right now (wrong bitmap format) if (fAppCursor != NULL)
// if (fAppCursor) fDesktop->HWInterface()->SetCursor(fAppCursor);
// fDesktop->HWInterface()->SetCursor(fAppCursor);
fDesktop->HWInterface()->SetCursorVisible(fCursorHideLevel == 0); fDesktop->HWInterface()->SetCursorVisible(fCursorHideLevel == 0);
} }
@@ -886,95 +877,76 @@ ServerApp::_DispatchMessage(int32 code, BPrivate::LinkReceiver& link)
fLink.Flush(); fLink.Flush();
break; break;
} }
case AS_SET_CURSOR_DATA: case AS_SET_CURSOR:
{ {
STRACE(("ServerApp %s: SetCursor via cursor data\n", Signature())); STRACE(("ServerApp %s: SetCursor\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()));
// Attached data: // Attached data:
// 1) bool flag to send a reply // 1) bool flag to send a reply
// 2) int32 token ID of the cursor to set // 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. // 3) port_id port to receive a reply. Only exists if the sync flag is true.
bool sync; bool sync;
int32 ctoken = B_NULL_TOKEN; int32 token = B_NULL_TOKEN;
link.Read<bool>(&sync);
link.Read<int32>(&ctoken);
ServerCursor *cursor = fDesktop->GetCursorManager().FindCursor(ctoken); link.Read<bool>(&sync);
if (cursor) link.Read<int32>(&token);
fDesktop->HWInterface()->SetCursor(cursor);
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) { if (sync) {
// the application is expecting a reply so that it // The application is expecting a reply
// knows the cursor shape has truely changed
fLink.StartMessage(B_OK); fLink.StartMessage(B_OK);
fLink.Flush(); fLink.Flush();
} }
break; 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: // Attached data:
// 1) 68 bytes of fAppCursor data // 1) 68 bytes of fAppCursor data
// 2) port_id reply port // 2) port_id reply port
status_t status = B_ERROR;
int8 cursorData[68]; int8 cursorData[68];
link.Read(cursorData, sizeof(cursorData)); ServerCursor* cursor = NULL;
// Because we don't want an overaccumulation of these particular if (link.Read(cursorData, sizeof(cursorData)) >= B_OK) {
// cursors, we will delete them if there is an existing one. It would cursor = new (nothrow) ServerCursor(cursorData);
// otherwise be easy to crash the server by calling CreateCursor a if (cursor == NULL)
// sufficient number of times status = B_NO_MEMORY;
if (fAppCursor) }
fDesktop->GetCursorManager().DeleteCursor(fAppCursor->ID());
fAppCursor = new ServerCursor(cursorData); if (cursor != NULL) {
fAppCursor->SetOwningTeam(fClientTeam); cursor->SetOwningTeam(fClientTeam);
fAppCursor->SetAppSignature(Signature()); fDesktop->GetCursorManager().AddCursor(cursor);
fDesktop->GetCursorManager().AddCursor(fAppCursor);
// Synchronous message - BApplication is waiting on the cursor's ID
fLink.StartMessage(B_OK);
fLink.Attach<int32>(cursor->Token());
} else
fLink.StartMessage(status);
// Synchronous message - BApplication is waiting on the cursor's ID
fLink.StartMessage(B_OK);
fLink.Attach<int32>(fAppCursor->ID());
fLink.Flush(); fLink.Flush();
break; break;
} }
case AS_DELETE_BCURSOR: case AS_DELETE_CURSOR:
{ {
STRACE(("ServerApp %s: Delete BCursor\n", Signature())); STRACE(("ServerApp %s: Delete BCursor\n", Signature()));
// Attached data: // Attached data:
// 1) int32 token ID of the cursor to delete // 1) int32 token ID of the cursor to delete
int32 ctoken = B_NULL_TOKEN; int32 token = B_NULL_TOKEN;
link.Read<int32>(&ctoken); link.Read<int32>(&token);
if (fAppCursor && fAppCursor->ID() == ctoken) if (fAppCursor && fAppCursor->Token() == token)
fAppCursor = NULL; fAppCursor = NULL;
fDesktop->GetCursorManager().DeleteCursor(ctoken); fDesktop->GetCursorManager().DeleteCursor(token);
break; break;
} }
+12 -3
View File
@@ -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:
@@ -10,6 +10,7 @@
#include "ServerBitmap.h" #include "ServerBitmap.h"
#include <new> #include <new>
#include <stdio.h>
#include <string.h> #include <string.h>
using std::nothrow; using std::nothrow;
@@ -26,7 +27,7 @@ using std::nothrow;
\param screen Screen assigned to the bitmap. \param screen Screen assigned to the bitmap.
*/ */
ServerBitmap::ServerBitmap(BRect rect, color_space space, ServerBitmap::ServerBitmap(BRect rect, color_space space,
int32 flags, int32 bytesPerLine, int32 flags, int32 bytesPerRow,
screen_id screen) screen_id screen)
: fInitialized(false), : fInitialized(false),
fArea(B_ERROR), fArea(B_ERROR),
@@ -44,7 +45,7 @@ ServerBitmap::ServerBitmap(BRect rect, color_space space,
fBitsPerPixel(0) fBitsPerPixel(0)
// TODO: what about fToken and fOffset ?!? // 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 - // #pragma mark -
+25 -33
View File
@@ -1,32 +1,25 @@
//------------------------------------------------------------------------------ /*
// Copyright (c) 2001-2002, Haiku, Inc. * Copyright 2001-2006, Haiku.
// * Distributed under the terms of the MIT License.
// Permission is hereby granted, free of charge, to any person obtaining a *
// copy of this software and associated documentation files (the "Software"), * Authors:
// to deal in the Software without restriction, including without limitation * DarkWyrm <bpmagic@columbus.rr.com>
// the rights to use, copy, modify, merge, publish, distribute, sublicense, * Stephan Aßmus <superstippi@gmx.de>
// and/or sell copies of the Software, and to permit persons to whom the * Axel Dörfler, axeld@pinc-software.de
// 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. Although descended from ServerBitmaps, ServerCursors are not handled by
// the BitmapManager - they are allocated like any other object. Unlike BeOS
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR R5, cursors can be any size or color space, and this class accomodates and
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, expands the R5 API.
// 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 <[email protected]>
// Stephan Aßmus <[email protected]>
// Description: Glorified ServerBitmap used for cursor work.
//
//------------------------------------------------------------------------------
#include "ServerCursor.h" #include "ServerCursor.h"
#include <stdio.h> #include <stdio.h>
/*! /*!
\brief Constructor \brief Constructor
\param r Size of the cursor \param r Size of the cursor
@@ -48,6 +41,7 @@ ServerCursor::ServerCursor(BRect r, color_space format,
_AllocateBuffer(); _AllocateBuffer();
} }
/*! /*!
\brief Constructor \brief Constructor
\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
@@ -112,6 +106,7 @@ ServerCursor::ServerCursor(const int8* data)
} }
} }
/*! /*!
\brief Constructor \brief Constructor
\param data Pointer to bitmap data in memory, the padding bytes should be contained when format less than 32 bpp. \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()); memcpy(Bits(), alreadyPaddedData, BitsLength());
} }
/*! /*!
\brief Copy constructor \brief Copy constructor
\param cursor cursor to copy \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 //! Frees the heap space allocated for the cursor's image data
ServerCursor::~ServerCursor() ServerCursor::~ServerCursor()
{ {
_FreeBuffer(); _FreeBuffer();
} }
/*! /*!
\brief Sets the cursor's hotspot \brief Sets the cursor's hotspot
\param pt New location of hotspot, constrained to the cursor's boundaries. \param pt New location of hotspot, constrained to the cursor's boundaries.
@@ -166,9 +164,3 @@ ServerCursor::SetHotSpot(BPoint pt)
fHotSpot.ConstrainTo(Bounds()); fHotSpot.ConstrainTo(Bounds());
} }
// SetAppSignature
void
ServerCursor::SetAppSignature(const char* signature)
{
fAppSignature.SetTo((signature) ? signature : "");
}
+7 -7
View File
@@ -1243,16 +1243,16 @@ ServerWindow::_DispatchViewMessage(int32 code,
fCurrentLayer->SetResizeMode(resizeMode); fCurrentLayer->SetResizeMode(resizeMode);
break; 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())); DTRACE(("ServerWindow %s: Message AS_LAYER_CURSOR: ViewLayer: %s - NOT IMPLEMENTED\n", Title(), fCurrentLayer->Name()));
int32 token = -1; int32 token;
link.Read<int32>(&token); if (link.Read<int32>(&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! // TODO: if fCurrentLayer is the view under the cursor, the appearance should change immediately!
break; break;
} }
+6 -4
View File
@@ -988,13 +988,15 @@ WindowLayer::MouseMoved(BMessage *msg, BPoint where, int32* _viewToken,
// new app cursor shouldn't override view cursor, ... // new app cursor shouldn't override view cursor, ...
ServerCursor* currentCursor = fDesktop->HWInterface()->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 != currentCursor) { if (cursor == NULL)
// TODO: custom cursors cannot be drawn by the HWInterface right now (wrong bitmap format) cursor = fDesktop->GetCursorManager().GetCursor(B_CURSOR_DEFAULT);
// fDesktop->HWInterface()->SetCursor(cursor);
} if (cursor != currentCursor && cursor != NULL)
fDesktop->HWInterface()->SetCursor(cursor);
} }
} }
+15 -5
View File
@@ -40,8 +40,11 @@ HWInterface::HWInterface(bool doubleBuffered)
HWInterface::~HWInterface() HWInterface::~HWInterface()
{ {
delete fCursorAreaBackup; delete fCursorAreaBackup;
delete fCursor;
delete fCursorAndDragBitmap; // The standard cursor doesn't belong us - the drag bitmap might
if (fCursor != fCursorAndDragBitmap)
delete fCursorAndDragBitmap;
delete fUpdateExecutor; delete fUpdateExecutor;
} }
@@ -81,17 +84,24 @@ HWInterface::SetCursor(ServerCursor* cursor)
// considered iritating to the user to // considered iritating to the user to
// change cursor shapes while something // change cursor shapes while something
// is dragged anyways. // is dragged anyways.
// TODO: like a "+" or "-" sign when dragging some files to indicate
// the current drag mode?
WriteUnlock(); WriteUnlock();
return; return;
} }
if (fCursor != cursor) { if (fCursor != cursor) {
BRect oldFrame = _CursorFrame(); BRect oldFrame = _CursorFrame();
delete fCursor;
if (fCursorAndDragBitmap == fCursor) {
// make sure _AdoptDragBitmap doesn't delete a real cursor
fCursorAndDragBitmap = NULL;
}
fCursor = cursor; fCursor = cursor;
Invalidate(oldFrame); Invalidate(oldFrame);
BRect r = _CursorFrame();
_AdoptDragBitmap(fDragBitmap, fDragBitmapOffset); _AdoptDragBitmap(fDragBitmap, fDragBitmapOffset);
Invalidate(r); Invalidate(_CursorFrame());
} }
WriteUnlock(); WriteUnlock();
} }