diff --git a/src/servers/app/server/CursorManager.cpp b/src/servers/app/server/CursorManager.cpp new file mode 100644 index 0000000000..46e00eccde --- /dev/null +++ b/src/servers/app/server/CursorManager.cpp @@ -0,0 +1,505 @@ +//------------------------------------------------------------------------------ +// 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: CursorManager.cpp +// Author: DarkWyrm +// Description: Handles the system's cursor infrastructure +// +//------------------------------------------------------------------------------ +#include "CursorManager.h" +#include "ServerCursor.h" +#include + +//! Initializes the CursorManager +CursorManager::CursorManager(void) +{ + _cursorlist=new BList(0); + _lock=create_sem(1,"cursor_manager_sem"); + + // Error code for AddCursor + _tokenizer.ExcludeValue(B_ERROR); + + // Set system cursors to "unassigned" + _defaultcsr=NULL; + _textcsr=NULL; + _movecsr=NULL; + _dragcsr=NULL; + _resizecsr=NULL; + _resize_nwse_csr=NULL; + _resize_nesw_csr=NULL; + _resize_ns_csr=NULL; + _resize_ew_csr=NULL; +} + +//! Does all the teardown +CursorManager::~CursorManager(void) +{ + ServerCursor *temp; + for(int32 i=0; i<_cursorlist->CountItems();i++) + { + temp=(ServerCursor*)_cursorlist->ItemAt(i); + if(temp) + delete temp; + } + _cursorlist->MakeEmpty(); + delete _cursorlist; + + delete_sem(_lock); + + // Note that it is not necessary to remove and delete the system + // cursors. These cursors are kept in the list with a NULL application + // signature so they cannot be removed very easily except via + // SetCursor(cursor_which). At shutdown, they are removed with the + // above loop. +} + +/*! + \brief Registers a cursor with the manager. + \param sc ServerCursor object to register + \return The token assigned to the cursor or B_ERROR if sc is NULL +*/ +int32 CursorManager::AddCursor(ServerCursor *sc) +{ + if(!sc) + return B_ERROR; + + acquire_sem(_lock); + _cursorlist->AddItem(sc); + int32 value=_tokenizer.GetToken(); + sc->_token=value; + release_sem(_lock); + + return value; +} + +/*! + \brief Removes a cursor from the internal list and deletes it + \param token ID value of the cursor to be deleted + + If the cursor is not found, this call does nothing +*/ +void CursorManager::DeleteCursor(int32 token) +{ + acquire_sem(_lock); + + ServerCursor *temp; + for(int32 i=0; i<_cursorlist->CountItems();i++) + { + temp=(ServerCursor*)_cursorlist->ItemAt(i); + if(temp && temp->_token==token) + { + _cursorlist->RemoveItem(i); + delete temp; + break; + } + } + release_sem(_lock); +} + +/*! + \brief Removes and deletes all of an application's cursors + \param signature Signature to which the cursors belong +*/ +void CursorManager::RemoveAppCursors(const char *signature) +{ + // OPTIMIZATION: For an optimization, it perhaps may be wise down + // the road to replace the ServerCursor's app signature with a + // pointer to its application and compare ServerApp pointers instead. + acquire_sem(_lock); + + ServerCursor *temp; + for(int32 i=0; i<_cursorlist->CountItems();i++) + { + temp=(ServerCursor*)_cursorlist->ItemAt(i); + if(temp && temp->_app_signature && + strcmp(signature, temp->_app_signature)==0) + { + _cursorlist->RemoveItem(i); + delete temp; + break; + } + } + release_sem(_lock); +} + +//! Wrapper around the DisplayDriver ShowCursor call +void CursorManager::ShowCursor(void) +{ + acquire_sem(_lock); + // TODO: enable this when Desktop.h is added to server +// DisplayDriver *driver=GetGfxDriver(); +// driver->ShowCursor(); + release_sem(_lock); +} + +//! Wrapper around the DisplayDriver HideCursor call +void CursorManager::HideCursor(void) +{ + acquire_sem(_lock); + // TODO: enable this when Desktop.h is added to server +// DisplayDriver *driver=GetGfxDriver(); +// driver->HideCursor(); + release_sem(_lock); +} + +//! Wrapper around the DisplayDriver ObscureCursor call +void CursorManager::ObscureCursor(void) +{ + acquire_sem(_lock); + // TODO: enable this when Desktop.h is added to server +// DisplayDriver *driver=GetGfxDriver(); +// driver->ObscureCursor(); + release_sem(_lock); +} + +/*! + \brief Set the screen's cursor + \param token ID of the screen's new cursor +*/ +void CursorManager::SetCursor(int32 token) +{ + acquire_sem(_lock); + ServerCursor *c=_FindCursor(token); + if(c) + { + // TODO: enable this when Desktop.h is added to server +// DisplayDriver *driver=GetGfxDriver(); +// driver->SetCursor(c); + } + release_sem(_lock); +} + +void CursorManager::SetCursor(cursor_which which) +{ + acquire_sem(_lock); + + // TODO: enable this when Desktop.h is added to server +/* DisplayDriver *driver=GetGfxDriver(); + switch(which) + { + case B_CURSOR_DEFAULT: + { + driver->SetCursor(_defaultcsr); + break; + } + case B_CURSOR_TEXT: + { + driver->SetCursor(_textcsr); + break; + } + case B_CURSOR_MOVE: + { + driver->SetCursor(_movecsr); + break; + } + case B_CURSOR_DRAG: + { + driver->SetCursor(_dragcsr); + break; + } + case B_CURSOR_RESIZE: + { + driver->SetCursor(_resizecsr); + break; + } + case B_CURSOR_RESIZE_NWSE: + { + driver->SetCursor(_resize_nwse_csr); + break; + } + case B_CURSOR_RESIZE_NESW: + { + driver->SetCursor(_resize_nesw_csr); + break; + } + case B_CURSOR_RESIZE_NS: + { + driver->SetCursor(_resize_ns_csr); + break; + } + case B_CURSOR_RESIZE_EW: + { + driver->SetCursor(_resize_ew_csr); + break; + } + default: + break; + } +*/ + release_sem(_lock); +} + +/*! + \brief Acquire the cursor which is used for a particular system cursor + \param which Which system cursor to get + \return Pointer to the particular cursor used or NULL if which is + invalid or the cursor has not been assigned +*/ +ServerCursor *CursorManager::GetCursor(cursor_which which) +{ + ServerCursor *temp=NULL; + + acquire_sem(_lock); + + switch(which) + { + case B_CURSOR_DEFAULT: + { + temp=_defaultcsr; + break; + } + case B_CURSOR_TEXT: + { + temp=_textcsr; + break; + } + case B_CURSOR_MOVE: + { + temp=_movecsr; + break; + } + case B_CURSOR_DRAG: + { + temp=_dragcsr; + break; + } + case B_CURSOR_RESIZE: + { + temp=_resizecsr; + break; + } + case B_CURSOR_RESIZE_NWSE: + { + temp=_resize_nwse_csr; + break; + } + case B_CURSOR_RESIZE_NESW: + { + temp=_resize_nesw_csr; + break; + } + case B_CURSOR_RESIZE_NS: + { + temp=_resize_ns_csr; + break; + } + case B_CURSOR_RESIZE_EW: + { + temp=_resize_ew_csr; + break; + } + default: + break; + } + + release_sem(_lock); + return temp; +} + +/*! + \brief Gets the current system cursor value + \return The current cursor value or CURSOR_OTHER if some non-system cursor +*/ +cursor_which CursorManager::GetCursorWhich(void) +{ + cursor_which temp; + + acquire_sem(_lock); + temp=_current_which; + release_sem(_lock); + return temp; +} + +/*! + \brief Sets the specified system cursor to the a particular cursor + \param which Which system cursor to change + \param token The ID of the cursor to become the new one + + A word of warning: once a cursor has been assigned to the system, the + system will take ownership of the cursor and deleting the cursor + will have not effect on the system. +*/ +void CursorManager::ChangeCursor(cursor_which which, int32 token) +{ + acquire_sem(_lock); + + // Find the cursor, based on the token + ServerCursor *cursor=_FindCursor(token); + + // Did we find a cursor with this token? + if(!cursor) + { + release_sem(_lock); + return; + } + + // Do the assignment + switch(which) + { + case B_CURSOR_DEFAULT: + { + if(_defaultcsr) + delete _defaultcsr; + + _defaultcsr=cursor; + + if(cursor->_app_signature) + { + delete cursor->_app_signature; + cursor->_app_signature=NULL; + } + break; + } + case B_CURSOR_TEXT: + { + if(_textcsr) + delete _textcsr; + + _textcsr=cursor; + + if(cursor->_app_signature) + { + delete cursor->_app_signature; + cursor->_app_signature=NULL; + } + break; + } + case B_CURSOR_MOVE: + { + if(_movecsr) + delete _movecsr; + + _movecsr=cursor; + + if(cursor->_app_signature) + { + delete cursor->_app_signature; + cursor->_app_signature=NULL; + } + break; + } + case B_CURSOR_DRAG: + { + if(_dragcsr) + delete _dragcsr; + + _dragcsr=cursor; + + if(cursor->_app_signature) + { + delete cursor->_app_signature; + cursor->_app_signature=NULL; + } + break; + } + case B_CURSOR_RESIZE: + { + if(_resizecsr) + delete _resizecsr; + + _resizecsr=cursor; + + if(cursor->_app_signature) + { + delete cursor->_app_signature; + cursor->_app_signature=NULL; + } + break; + } + case B_CURSOR_RESIZE_NWSE: + { + if(_resize_nwse_csr) + delete _resize_nwse_csr; + + _resize_nwse_csr=cursor; + + if(cursor->_app_signature) + { + delete cursor->_app_signature; + cursor->_app_signature=NULL; + } + break; + } + case B_CURSOR_RESIZE_NESW: + { + if(_resize_nesw_csr) + delete _resize_nesw_csr; + + _resize_nesw_csr=cursor; + + if(cursor->_app_signature) + { + delete cursor->_app_signature; + cursor->_app_signature=NULL; + } + break; + } + case B_CURSOR_RESIZE_NS: + { + if(_resize_ns_csr) + delete _resize_ns_csr; + + _resize_ns_csr=cursor; + + if(cursor->_app_signature) + { + delete cursor->_app_signature; + cursor->_app_signature=NULL; + } + break; + } + case B_CURSOR_RESIZE_EW: + { + if(_resize_ew_csr) + delete _resize_ew_csr; + + _resize_ew_csr=cursor; + + if(cursor->_app_signature) + { + delete cursor->_app_signature; + cursor->_app_signature=NULL; + } + break; + } + default: + break; + } + + release_sem(_lock); +} + +/*! + \brief Internal function which finds the cursor with a particular ID + \param token ID of the cursor to find + \return The cursor or NULL if not found +*/ +ServerCursor *CursorManager::_FindCursor(int32 token) +{ + ServerCursor *temp; + for(int32 i=0; i<_cursorlist->CountItems();i++) + { + temp=(ServerCursor*)_cursorlist->ItemAt(i); + if(temp && temp->_token==token) + return temp; + } + return NULL; +} diff --git a/src/servers/app/server/CursorManager.h b/src/servers/app/server/CursorManager.h new file mode 100644 index 0000000000..970842e7ea --- /dev/null +++ b/src/servers/app/server/CursorManager.h @@ -0,0 +1,97 @@ +//------------------------------------------------------------------------------ +// 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: CursorManager.h +// Author: DarkWyrm +// Description: Handles the system's cursor infrastructure +// +//------------------------------------------------------------------------------ +#ifndef CURSORMANAGER_H_ +#define CURSORMANAGER_H_ + +#include +#include +#include "TokenHandler.h" + +class ServerCursor; + +// Duplicate definition - do NOT include or errors will abound... +// We do this so that we don't have to modify R5's headers in order to compile +typedef enum +{ + B_CURSOR_DEFAULT=0, + B_CURSOR_TEXT, + B_CURSOR_MOVE, + B_CURSOR_DRAG, + B_CURSOR_RESIZE, + B_CURSOR_RESIZE_NWSE, + B_CURSOR_RESIZE_NESW, + B_CURSOR_RESIZE_NS, + B_CURSOR_RESIZE_EW, + B_CURSOR_OTHER +} cursor_which; + +/*! + \class CursorManager CursorManager.h + \brief Handles almost all cursor management functions for the system + + The Cursor manager provides system cursor support, previous unseen on + any BeOS platform. It also provides tokens for BCursors and frees all + of an application's cursors whenever an application closes. +*/ +class CursorManager +{ +public: + CursorManager(void); + ~CursorManager(void); + int32 AddCursor(ServerCursor *sc); + void DeleteCursor(int32 token); + void RemoveAppCursors(const char *signature); + void ShowCursor(void); + void HideCursor(void); + void ObscureCursor(void); + void SetCursor(int32 token); + void SetCursor(cursor_which which); + ServerCursor *GetCursor(cursor_which which); + cursor_which GetCursorWhich(void); + void ChangeCursor(cursor_which which, int32 token); + +private: + ServerCursor *_FindCursor(int32 token); + + BList *_cursorlist; + TokenHandler _tokenizer; + sem_id _lock; + + // System cursor members + ServerCursor *_defaultcsr, + *_textcsr, + *_movecsr, + *_dragcsr, + *_resizecsr, + *_resize_nwse_csr, + *_resize_nesw_csr, + *_resize_ns_csr, + *_resize_ew_csr; + cursor_which _current_which; +}; + +#endif \ No newline at end of file diff --git a/src/servers/app/server/Jamfile b/src/servers/app/server/Jamfile index 4bf11a8676..cdbfc5028c 100644 --- a/src/servers/app/server/Jamfile +++ b/src/servers/app/server/Jamfile @@ -13,24 +13,25 @@ Server app_server : # against libopenbeos ColorUtils.cc ColorSet.cpp - Decorator.cpp - SystemPalette.cpp - RGBColor.cpp RectUtils.cpp + RGBColor.cpp + SystemPalette.cpp - # Operating Classes + # Manager Classes AppServer.cpp - ServerBitmap.cpp - ServerCursor.cpp + CursorManager.cpp # Font Classes FontFamily.cpp FontServer.cpp ServerFont.cpp - # Display Modules - DisplayDriver.cpp + # Display Classes AccelerantDriver.cpp + Decorator.cpp + DisplayDriver.cpp + ServerBitmap.cpp + ServerCursor.cpp ; LinkSharedOSLibs app_server : be root game translation libfreetype.so ; diff --git a/src/servers/app/server/ServerCursor.h b/src/servers/app/server/ServerCursor.h index 747defaa30..7957332786 100644 --- a/src/servers/app/server/ServerCursor.h +++ b/src/servers/app/server/ServerCursor.h @@ -60,7 +60,7 @@ private: BPoint _hotspot; char *_app_signature; - int32 token; + int32 _token; }; #endif \ No newline at end of file