From b010ca67201c6b96d2136d4feca376bb9afe9a57 Mon Sep 17 00:00:00 2001 From: DarkWyrm Date: Tue, 22 Oct 2002 00:08:45 +0000 Subject: [PATCH] Checkin for Gabe Yoder git-svn-id: file:///srv/svn/repos/haiku/trunk/current@1590 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../app/usecases/BClipboardUseCases.html | 153 +++++++ .../develop/app/usecases/BCursorUseCases.html | 50 +++ headers/private/app/RegistrarDefs.h | 8 + src/kits/app/Clipboard.cpp | 399 +++++++++++------- src/servers/registrar/ClipboardHandler.cpp | 133 ++++++ src/servers/registrar/ClipboardHandler.h | 5 + src/servers/registrar/ClipboardTree.cpp | 119 ++++++ src/servers/registrar/ClipboardTree.h | 37 ++ src/servers/registrar/Jamfile | 1 + 9 files changed, 746 insertions(+), 159 deletions(-) create mode 100644 docs/develop/app/usecases/BClipboardUseCases.html create mode 100644 docs/develop/app/usecases/BCursorUseCases.html create mode 100644 src/servers/registrar/ClipboardTree.cpp create mode 100644 src/servers/registrar/ClipboardTree.h diff --git a/docs/develop/app/usecases/BClipboardUseCases.html b/docs/develop/app/usecases/BClipboardUseCases.html new file mode 100644 index 0000000000..1be0580386 --- /dev/null +++ b/docs/develop/app/usecases/BClipboardUseCases.html @@ -0,0 +1,153 @@ + + +BClipboard Use Cases and Implementation Details + + + + + + +

BClipboard Use Cases and Implementation Details:

+ +

This document describes the BClipboard interface and some basics of how it is implemented. +The document has the following sections:

+ +
    +
  1. BClipboard Interface
  2. +
  3. BClipboard Use Cases
  4. +
  5. BClipboard Implementation
  6. +
+ +

BClipboard Interface:

+ +

The BClipboard class provides an interface to a named, system-wide, temporary storage resource. +Access to the system clipboard is provided by the be_clipboard variable provided by a BApplication object (or by constructing a clipboard with the name "system"). +The best source of information for the BClipboard interface can be found +here in the Be Book. +

+ +

BClipboard Use Cases:

+ +

The following use cases cover the BClipboard functionality:

+ +
    +
  1. Construction: A BClipboard will accept one or two arguments to construction. +A name is required for identifying the clipboard. The discard argument indicates whether the +clipboard data should be discarded between boots. Te discard argument defaults to false, however +this is meaningless since functionality has not been implemented to maintain clipboard data +between boots. +After construction, the queue is empty.

  2. + +
  3. Destruction: The destructor destroys the BClipboard object, however the system-wide clipboard itself is unaffected.

  4. + +
  5. Writing to clipboard 1: +The normal procedure for writing data consists of the following: locking the clipboard via Lock(), clearing the +data via Clear(), adding data to the clipboard message, committing the data via Commit(), and unlocking the +clipboard via Unlock(). +

  6. + +
  7. Writing to clipboard 2: +The data which is to be written is not added directly to the BClipboard object, but is added to the data +message for the BClipboard. The message is obtained by calling BClipboard::Data(). Data is added in fields +of type B_MIME_TYPE. The name of the field corresponds to the MIME type of the data. If multiple fields are +added, they should contain the same data, but formatted for different MIME types. +

  8. + +
  9. Writing to clipboard 3: +In the event that one wishes to back out of writing process before calling Commit(), Revert() must be called. +Otherwise, the changes to the clipboard remain in the BClipboard object. +

  10. + +
  11. Reading from clipboard 1: +The normal procedure for reading data consists of the following: locking the clipboard via Lock(), obtaining +the data from the clipboards data message, and unlocking the clipboard via Unlock(). +

  12. + +
  13. Reading from clipboard 2: +The data message is obtained from a call to BClipboard::Data(). Data is obtained from the message by using +BMessage::FindData for a specified MIME type. +

  14. + +
  15. Reading from clipboard 3: +The data is uploaded from the system when Lock() is called, therefore any data which is written to the clipboard +between the calls to Lock() and Data() will not be included in the data message. +

  16. + +
  17. Reading from clipboard 4: +It is permissible to Unlock() the clipboard before calling FindData on the data message. +

  18. + +
  19. Clearing: +The Clear() function is used to remove all data from the clipboard and is used before adding new data which is +to be written to the clipboard. Clear() returns B_ERROR if the BClipboard is not locked, and returns B_OK if +it is locked. +

  20. + +
  21. Committing: +The Commit() function is used to upload data from the BClipboard to the system. The data is immediately +available to other applications once Commit() has been called. Commit() returns B_ERROR if the BClipboard +is not locked, and returns B_OK if it is locked. +

  22. + +
  23. Revert: +The Revert() function is used to synchronize the data in the BClipboard to the system. This is only needed in +case one begins to modify the data message and wishes to back out of the changes. Revert() returns B_ERROR if +the BClipboard is not locked, and returns B_OK if it is locked. +

  24. + +
  25. Accessing data: +Data() is used to obtain a pointer to the BClipboard's data message. One is expected to read and write data +directly to the message, but the message must not be freed or dispatched. Data() returns NULL if the +BClipboard is not locked. +

  26. + +
  27. Accessing a data source: +DataSource() is used to obtain a BMessenger pointed at the BApplication which last committed data to the +clipboard. There is no requirement for the the BClipboard to be locked when calling DataSource(). +

  28. + +
  29. Obtaining a count: +The count refers to the number of times that data has been uploaded to the clipboard. +There are two count functions. SystemCount() returns an up to date count which is obtained from the system. +Count() returns a cached count. The cached count is set to zero upon creation +of the BClipboard, and is updated when Lock() or Commit() is called. +

  30. + +
  31. Locking: +Lock() is used to upload data from the system into the BClipboard object and prevent other threads in the +application from using it. It must be called before reading or writing data to the BClipboard. It blocks +if the BClipboard is already locked. The return value is true if the BClipboard is successfully locked, or +false if the BClipboard was deleted while Lock() was blocked. +

  32. + +
  33. Unlocking: +Unlock() is used to unlock the BClipboard and allow other threads in the application to use it. +

  34. + +
  35. Checking lock status: +IsLocked() returns true if the BClipboard is locked, and false if it is not locked. +

  36. + +
  37. Checking clipboard name: +Name() returns a string containing the name of the clipboard. It is not necessary for the BClipboard to be +locked when calling Name(). +

  38. + +
  39. Watching a clipboard: +StartWatching and StopWatching are used to enable and disable watching of a clipboard. When the clipboard is +changed, a B_CLIPBOARD_CHANGED message is sent to the target specified in the call to StartWatching. +

  40. + +
+ +

BClipboard Implementation:

+ +

+The BClipboard class is implemented via a message passing system between the BClipboard, the Roster, and +the Clipboard Handler associated with the Roster. Details of the message passing protocol are listed in the +Roster documentation. +

+ + + + diff --git a/docs/develop/app/usecases/BCursorUseCases.html b/docs/develop/app/usecases/BCursorUseCases.html new file mode 100644 index 0000000000..2f2a2fc7dd --- /dev/null +++ b/docs/develop/app/usecases/BCursorUseCases.html @@ -0,0 +1,50 @@ + + +BCursor Use Cases and Implementation Details + + + + + + +

BCursor Use Cases and Implementation Details:

+ +

This document describes the BCursor interface and some basics of how it is implemented. +The document has the following sections:

+ +
    +
  1. BCursor Interface
  2. +
  3. BCursor Use Cases
  4. +
  5. BCursor Implementation
  6. +
+ +

BCursor Interface:

+ +

The BCursor class is a simple class used to represent a mouse cursor as an object instead of an array of pixel data. The best source of information for the BCursor interface can be found +here in the Be Book. +

+ +

BCursor Use Cases:

+ +

The following use cases cover the BCursor functionality:

+ +
    +
  1. Construction 1: The first BCursor constructor requires a pointer to the pixel data. The format for the pixel data is described +here in the Be Book. +This pixel data is used to initialize the BCursor, but BCursor does not take ownership of the data, therefore you are responsible for freeing the memory after construction.

  2. + +
  3. Construction 2: The second BCursor constructor requires a BMessage as an archive, however BCursor does not currently support archiving. Do not use this constructor.

  4. + +
  5. Destruction: This releases all resources used by the BCursor.

  6. + +
  7. Instantiate: This always returns NULL since it relies on the second constructor (which is not currently supported). If it were implemented, this would return a new BArchivable consisting of a BCursor created from the archive passed in as an argument.

  8. + +
+ +

BCursor Implementation:

+ +

All meaningful work of the BCursor is implemented in the first constructor. The constructor establishes a link with the app_server and sends it the pixel data. The app_server provides the BCursor with a token which identifies the pixel data. When BApplication::SetCursor(BCursor) is called, it must get the needed cursor data by obtaining the BCursor's token (BApplication is a friend of BCursor) and using the token to request the data from the app_server. Note that BCursor does not internally store the pixel data.

+ + + + diff --git a/headers/private/app/RegistrarDefs.h b/headers/private/app/RegistrarDefs.h index 839e9f5d97..522306c149 100644 --- a/headers/private/app/RegistrarDefs.h +++ b/headers/private/app/RegistrarDefs.h @@ -81,6 +81,13 @@ enum { B_REG_GET_MESSAGE_RUNNER_INFO = 'rgri', // internal registrar messages B_REG_ROSTER_SANITY_EVENT = 'rgir', + // clipboard handler requests + B_REG_ADD_CLIPBOARD = 'rgca', + B_REG_GET_CLIPBOARD_COUNT = 'rgcc', + B_REG_CLIPBOARD_START_WATCHING = 'rgcw', + B_REG_CLIPBOARD_STOP_WATCHING = 'rgcx', + B_REG_DOWNLOAD_CLIPBOARD = 'rgcd', + B_REG_UPLOAD_CLIPBOARD = 'rgcu', }; // B_REG_MIME_SET_PARAM "which" constants @@ -127,3 +134,4 @@ struct flat_app_info { }; #endif // REGISTRAR_DEFS_H + diff --git a/src/kits/app/Clipboard.cpp b/src/kits/app/Clipboard.cpp index e9ede65562..6fed1dcd34 100644 --- a/src/kits/app/Clipboard.cpp +++ b/src/kits/app/Clipboard.cpp @@ -1,159 +1,240 @@ -//------------------------------------------------------------------------------ -// 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: Clipboard.cpp -// Author: Gabe Yoder (gyoder@stny.rr.com) -// Description: BClipboard provides an interface to a system-wide clipboard -// storage area. -//------------------------------------------------------------------------------ - -// Standard Includes ----------------------------------------------------------- -#include -#include - -// System Includes ------------------------------------------------------------- -#include - -// Project Includes ------------------------------------------------------------ - -// Local Includes -------------------------------------------------------------- - -// Local Defines --------------------------------------------------------------- - -// Globals --------------------------------------------------------------------- - - -//------------------------------------------------------------------------------ -BClipboard::BClipboard(const char *name, bool transient = false) -{ - /* Not complete yet */ - fName = strdup(name); - fData = new BMessage(); -} -//------------------------------------------------------------------------------ -BClipboard::~BClipboard() -{ - /* Not complete yet? */ - free(fName); - delete fData; -} -//------------------------------------------------------------------------------ -const char* BClipboard::Name() const -{ - return (const char*)fName; -} -//------------------------------------------------------------------------------ -uint32 BClipboard::LocalCount() const -{ - return fCount; -} -//------------------------------------------------------------------------------ -uint32 BClipboard::SystemCount() const -{ - /* Need to upload count data from app server, and update fCount */ - - return fCount; -} -//------------------------------------------------------------------------------ -status_t BClipboard::StartWatching(BMessenger target) -{ -} -//------------------------------------------------------------------------------ -status_t BClipboard::StopWatching(BMessenger target) -{ -} -//------------------------------------------------------------------------------ -bool BClipboard::Lock() -{ - bool retVal; - retVal = fLock.Lock(); - /* Still need to upload clipboard data to fData */ - /* Involves something with DownloadFromSystem */ - - return retVal; -} -//------------------------------------------------------------------------------ -void BClipboard::Unlock() -{ - fLock.Unlock(); -} -//------------------------------------------------------------------------------ -bool BClipboard::IsLocked() const -{ - return fLock.IsLocked(); -} -//------------------------------------------------------------------------------ -status_t BClipboard::Clear() -{ -} -//------------------------------------------------------------------------------ -status_t BClipboard::Commit() -{ -} -//------------------------------------------------------------------------------ -status_t BClipboard::Revert() -{ -} -//------------------------------------------------------------------------------ -BMessenger BClipboard::DataSource() const -{ -} -//------------------------------------------------------------------------------ -BMessage* BClipboard::Data() const -{ - if ( IsLocked() ) - return fData; - return NULL; -} -//------------------------------------------------------------------------------ -BClipboard::BClipboard(const BClipboard &) -{ -} -//------------------------------------------------------------------------------ -BClipboard & BClipboard::operator=(const BClipboard &) -{ -} -//------------------------------------------------------------------------------ -void BClipboard::_ReservedClipboard1() -{ -} -//------------------------------------------------------------------------------ -void BClipboard::_ReservedClipboard2() -{ -} -//------------------------------------------------------------------------------ -void BClipboard::_ReservedClipboard3() -{ -} -//------------------------------------------------------------------------------ -bool BClipboard::AssertLocked() const -{ -} -//------------------------------------------------------------------------------ -status_t BClipboard::DownloadFromSystem(bool force=false) -{ -} -//------------------------------------------------------------------------------ -status_t BClipboard::UploadToSystem() -{ -} -//------------------------------------------------------------------------------ - +//------------------------------------------------------------------------------ +// 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: Clipboard.cpp +// Author: Gabe Yoder (gyoder@stny.rr.com) +// Description: BClipboard provides an interface to a system-wide clipboard +// storage area. +//------------------------------------------------------------------------------ + +// Standard Includes ----------------------------------------------------------- +#include +#include +#include + +// System Includes ------------------------------------------------------------- +#include +#include +#include + +// Project Includes ------------------------------------------------------------ + +// Local Includes -------------------------------------------------------------- + +// Local Defines --------------------------------------------------------------- + +// Globals --------------------------------------------------------------------- + + +//------------------------------------------------------------------------------ +BClipboard::BClipboard(const char *name, bool transient = false) +{ + fName = strdup(name); + fData = new BMessage(); + fCount = 0; + fSystemCount = 0; + + BMessage message(B_REG_GET_CLIPBOARD_MESSENGER), reply; + if ( (_send_to_roster_(&message, &reply, false) == B_OK) && + (reply.what == B_REG_SUCCESS) && + (reply.FindMessenger("messenger",&fClipHandler) == B_OK) ) + { + BMessage handlerMessage(B_REG_ADD_CLIPBOARD), handlerReply; + int32 result; + if ( (handlerMessage.AddString("name",fName) == B_OK) && + (fClipHandler.SendMessage(&message, &reply) == B_OK) ) + reply.FindInt32("result",&result); + } +} +//------------------------------------------------------------------------------ +BClipboard::~BClipboard() +{ + free(fName); + delete fData; +} +//------------------------------------------------------------------------------ +const char* BClipboard::Name() const +{ + return (const char*)fName; +} +//------------------------------------------------------------------------------ +uint32 BClipboard::LocalCount() const +{ + /* fSystemCount contains the total number of writes to the clipboard. + fCount contains the number of writes to the clipboard done by this + BClipboard. + */ + return fSystemCount; +} +//------------------------------------------------------------------------------ +uint32 BClipboard::SystemCount() const +{ + int32 val; + BMessage message(B_REG_GET_CLIPBOARD_COUNT), reply; + if ( (message.AddString("name",fName) == B_OK) && + (fClipHandler.SendMessage(&message, &reply) == B_OK) && + (reply.FindInt32("count",&val) == B_OK) ) + return (uint32)val; + + return 0; +} +//------------------------------------------------------------------------------ +status_t BClipboard::StartWatching(BMessenger target) +{ + BMessage message(B_REG_CLIPBOARD_START_WATCHING), reply; + if ( (message.AddString("name",fName) == B_OK) && + (message.AddMessenger("target", target ) == B_OK) && + (fClipHandler.SendMessage(&message, &reply) == B_OK) ) + return B_OK; + return B_ERROR; +} +//------------------------------------------------------------------------------ +status_t BClipboard::StopWatching(BMessenger target) +{ + BMessage message(B_REG_CLIPBOARD_STOP_WATCHING), reply; + if ( (message.AddString("name",fName) == B_OK) && + (message.AddMessenger("target", target ) == B_OK) && + (fClipHandler.SendMessage(&message, &reply) == B_OK) ) + return B_OK; + return B_ERROR; +} +//------------------------------------------------------------------------------ +bool BClipboard::Lock() +{ + /* Will this work correctly if clipboard is deleted while still waiting on + fLock.Lock() ? */ + bool retVal; + retVal = fLock.Lock(); + if ( retVal && + (DownloadFromSystem() != B_OK) ) + { + retVal = false; + fLock.Unlock(); + } + + return retVal; +} +//------------------------------------------------------------------------------ +void BClipboard::Unlock() +{ + fLock.Unlock(); +} +//------------------------------------------------------------------------------ +bool BClipboard::IsLocked() const +{ + return fLock.IsLocked(); +} +//------------------------------------------------------------------------------ +status_t BClipboard::Clear() +{ + if ( AssertLocked() && + (fData->MakeEmpty() == B_OK) ) + return B_OK; + return B_ERROR; +} +//------------------------------------------------------------------------------ +status_t BClipboard::Commit() +{ + if ( AssertLocked() && + (UploadToSystem() == B_OK) ) + return B_OK; + return B_ERROR; +} +//------------------------------------------------------------------------------ +status_t BClipboard::Revert() +{ + if ( AssertLocked() && + (fData->MakeEmpty() == B_OK) && + (DownloadFromSystem() == B_OK) ) + return B_OK; + return B_ERROR; +} +//------------------------------------------------------------------------------ +BMessenger BClipboard::DataSource() const +{ + return fDataSource; +} +//------------------------------------------------------------------------------ +BMessage* BClipboard::Data() const +{ + if ( IsLocked() ) + return fData; + return NULL; +} +//------------------------------------------------------------------------------ +BClipboard::BClipboard(const BClipboard &) +{ + /* This is private, and I don't use it, so I'm not going to implement it */ +} +//------------------------------------------------------------------------------ +BClipboard & BClipboard::operator=(const BClipboard &) +{ + /* This is private, and I don't use it, so I'm not going to implement it */ +} +//------------------------------------------------------------------------------ +void BClipboard::_ReservedClipboard1() +{ +} +//------------------------------------------------------------------------------ +void BClipboard::_ReservedClipboard2() +{ +} +//------------------------------------------------------------------------------ +void BClipboard::_ReservedClipboard3() +{ +} +//------------------------------------------------------------------------------ +bool BClipboard::AssertLocked() const +{ + /* How should this be different from IsLocked() */ + return fLock.IsLocked(); +} +//------------------------------------------------------------------------------ +status_t BClipboard::DownloadFromSystem(bool force=false) +{ + /* What does force mean? */ + BMessage message(B_REG_DOWNLOAD_CLIPBOARD), reply; + if ( (message.AddString("name",fName) == B_OK) && + (fClipHandler.SendMessage(&message, &reply) == B_OK) && + (reply.FindMessage("data",fData) == B_OK) && + (reply.FindMessenger("data source",&fDataSource) == B_OK) && + (reply.FindInt32("count",(int32 *)(&fSystemCount)) == B_OK) ) + return B_OK; + return B_ERROR; +} +//------------------------------------------------------------------------------ +status_t BClipboard::UploadToSystem() +{ + BMessage message(B_REG_UPLOAD_CLIPBOARD), reply; + if ( (message.AddString("name",fName) == B_OK) && + (message.AddMessage("data",fData) == B_OK) && + (message.AddMessenger("data source", be_app_messenger ) == B_OK) && + (fClipHandler.SendMessage(&message, &reply) == B_OK) && + (reply.FindInt32("count",(int32 *)(&fSystemCount)) == B_OK) ) + { + fCount++; + return B_OK; + } + return B_ERROR; +} +//------------------------------------------------------------------------------ + + diff --git a/src/servers/registrar/ClipboardHandler.cpp b/src/servers/registrar/ClipboardHandler.cpp index 3c827d1606..79e8cf388b 100644 --- a/src/servers/registrar/ClipboardHandler.cpp +++ b/src/servers/registrar/ClipboardHandler.cpp @@ -1,6 +1,7 @@ // ClipboardHandler.cpp #include +#include #include "ClipboardHandler.h" @@ -32,10 +33,142 @@ ClipboardHandler::~ClipboardHandler() void ClipboardHandler::MessageReceived(BMessage *message) { + BString name; + BMessage reply; switch (message->what) { + B_REG_ADD_CLIPBOARD: + { + if ( message->FindString("name",&name) != B_OK ) + { + reply.AddInt32("result",0); + } + else + { + fClipboardTree.AddNode(name); + reply.AddInt32("result",1); + } + reply.what = B_REG_RESULT; + message->SendReply(&reply); + } + break; + B_REG_GET_CLIPBOARD_COUNT: + { + if ( message->FindString("name",&name) != B_OK ) + { + reply.AddInt32("result",0); + } + else + { + ClipboardTree *node = fClipboardTree.GetNode(name); + if ( node ) + { + reply.AddInt32("count",(uint32)(node->GetCount())); + reply.AddInt32("result",1); + } + else + reply.AddInt32("result",0); + } + reply.what = B_REG_RESULT; + message->SendReply(&reply); + } + break; + B_REG_CLIPBOARD_START_WATCHING: + { + BMessenger target; + if ( (message->FindString("name",&name) != B_OK) || + (message->FindMessenger("target",&target) != B_OK) ) + { + reply.AddInt32("result",0); + } + else + { + ClipboardTree *node = fClipboardTree.GetNode(name); + if ( node && node->AddWatcher(&target) ) + reply.AddInt32("result",1); + else + reply.AddInt32("result",0); + } + reply.what = B_REG_RESULT; + message->SendReply(&reply); + } + break; + B_REG_CLIPBOARD_STOP_WATCHING: + { + BMessenger target; + if ( (message->FindString("name",&name) != B_OK) || + (message->FindMessenger("target",&target) != B_OK) ) + { + reply.AddInt32("result",0); + } + else + { + ClipboardTree *node = fClipboardTree.GetNode(name); + if ( node && node->RemoveWatcher(&target) ) + reply.AddInt32("result",1); + else + reply.AddInt32("result",0); + } + reply.what = B_REG_RESULT; + message->SendReply(&reply); + } + break; + B_REG_DOWNLOAD_CLIPBOARD: + { + if ( message->FindString("name",&name) != B_OK ) + { + reply.AddInt32("result",0); + } + else + { + ClipboardTree *node = fClipboardTree.GetNode(name); + if ( node ) + { + reply.AddMessage("data",node->GetData()); + reply.AddMessenger("data source",*node->GetDataSource()); + reply.AddInt32("count",(uint32)(node->GetCount())); + reply.AddInt32("result",1); + } + else + reply.AddInt32("result",0); + } + reply.what = B_REG_RESULT; + message->SendReply(&reply); + } + break; + B_REG_UPLOAD_CLIPBOARD: + { + BMessage data; + BMessenger dataSource; + ClipboardTree *node = NULL; + if ( (message->FindString("name",&name) != B_OK) || + (message->FindMessage("data",&data) != B_OK) || + (message->FindMessenger("data source",&dataSource) != B_OK) ) + { + reply.AddInt32("result",0); + } + else + { + node = fClipboardTree.GetNode(name); + if ( node ) + { + node->SetData(&data); + node->SetDataSource(&dataSource); + reply.AddInt32("count",(uint32)(node->IncrementCount())); + reply.AddInt32("result",1); + } + else + reply.AddInt32("result",0); + } + reply.what = B_REG_RESULT; + message->SendReply(&reply); + if ( node ) + node->NotifyWatchers(); + } + break; default: BHandler::MessageReceived(message); break; } } + diff --git a/src/servers/registrar/ClipboardHandler.h b/src/servers/registrar/ClipboardHandler.h index a8a5d66e5c..6f9d13d570 100644 --- a/src/servers/registrar/ClipboardHandler.h +++ b/src/servers/registrar/ClipboardHandler.h @@ -4,6 +4,8 @@ #define CLIPBOARD_HANDLER_H #include +#include +#include "ClipboardTree.h" class ClipboardHandler : public BHandler { public: @@ -11,6 +13,9 @@ public: virtual ~ClipboardHandler(); virtual void MessageReceived(BMessage *message); +private: + ClipboardTree fClipboardTree; }; #endif // CLIPBOARD_HANDLER_H + diff --git a/src/servers/registrar/ClipboardTree.cpp b/src/servers/registrar/ClipboardTree.cpp new file mode 100644 index 0000000000..e588d3f9b1 --- /dev/null +++ b/src/servers/registrar/ClipboardTree.cpp @@ -0,0 +1,119 @@ +// ClipboardTree.cpp + +#include +#include + +#include "ClipboardTree.h" + +/*! + \class ClipboardTree + \brief Implements a tree containing clipboards and their data +*/ + +// constructor +/*! \brief Creates and initializes a ClipboardTree. +*/ +ClipboardTree::ClipboardTree() +{ + fName = ""; + fCount = 0; + fLeftChild = NULL; + fRightChild = NULL; +} + +// destructor +/*! \brief Frees all resources associate with this object. +*/ +ClipboardTree::~ClipboardTree() +{ + if ( fLeftChild ) + delete fLeftChild; + if ( fRightChild ) + delete fRightChild; +} + +void ClipboardTree::AddNode(BString name) +{ + if ( fName == "" ) + { + fName = name; + return; + } + if ( fName == name ) + return; + if ( name < fName ) + { + if ( !fLeftChild ) + fLeftChild = new ClipboardTree; + fLeftChild->AddNode(name); + return; + } + if ( !fRightChild ) + fRightChild = new ClipboardTree; + fRightChild->AddNode(name); +} + +ClipboardTree* ClipboardTree::GetNode(BString name) +{ + if ( fName == "" ) + return NULL; + if ( fName == name ) + return this; + if ( name < fName ) + { + if ( !fLeftChild ) + return NULL; + return fLeftChild->GetNode(name); + } + if ( !fRightChild ) + return NULL; + return fRightChild->GetNode(name); +} + +uint32 ClipboardTree::GetCount() +{ + return fCount; +} + +uint32 ClipboardTree::IncrementCount() +{ + fCount++; + return fCount; +} + +BMessage* ClipboardTree::GetData() +{ + return &fData; +} + +void ClipboardTree::SetData(BMessage *data) +{ + fData = *data; +} + +BMessenger* ClipboardTree::GetDataSource() +{ + return &fDataSource; +} + +void ClipboardTree::SetDataSource(BMessenger *dataSource) +{ + fDataSource = *dataSource; +} + +bool ClipboardTree::AddWatcher(BMessenger *watcher) +{ + return fWatchingService.AddWatcher(*watcher); +} + +bool ClipboardTree::RemoveWatcher(BMessenger *watcher) +{ + return fWatchingService.RemoveWatcher(*watcher,true); +} + +void ClipboardTree::NotifyWatchers() +{ + BMessage message(B_CLIPBOARD_CHANGED); + fWatchingService.NotifyWatchers(&message,NULL); +} + diff --git a/src/servers/registrar/ClipboardTree.h b/src/servers/registrar/ClipboardTree.h new file mode 100644 index 0000000000..19775f09e5 --- /dev/null +++ b/src/servers/registrar/ClipboardTree.h @@ -0,0 +1,37 @@ +// ClipboardTree.h + +#ifndef CLIPBOARD_TREE_H +#define CLIPBOARD_TREE_H + +#include +#include +#include +#include "WatchingService.h" + +class ClipboardTree { +public: + ClipboardTree(); + ~ClipboardTree(); + void AddNode(BString name); + ClipboardTree* GetNode(BString name); + uint32 GetCount(); + uint32 IncrementCount(); + BMessage *GetData(); + void SetData(BMessage *data); + BMessenger *GetDataSource(); + void SetDataSource(BMessenger *dataSource); + bool AddWatcher(BMessenger *watcher); + bool RemoveWatcher(BMessenger *watcher); + void NotifyWatchers(); +private: + BString fName; + BMessage fData; + BMessenger fDataSource; + ClipboardTree *fLeftChild; + ClipboardTree *fRightChild; + uint32 fCount; + WatchingService fWatchingService; +}; + +#endif // CLIPBOARD_TREE_H + diff --git a/src/servers/registrar/Jamfile b/src/servers/registrar/Jamfile index 14bad0b3d4..f11d4b68d1 100644 --- a/src/servers/registrar/Jamfile +++ b/src/servers/registrar/Jamfile @@ -7,6 +7,7 @@ UsePrivateHeaders storage ; Server obos_registrar : AppInfoList.cpp ClipboardHandler.cpp + ClipboardTree.cpp Event.cpp EventMaskWatcher.cpp EventQueue.cpp