This document describes the BClipboard interface and some basics of how it is implemented.
+The document has the following sections:
+
+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.
+
+
+
+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.
+
+Destruction: The destructor destroys the BClipboard object, however the system-wide clipboard itself is unaffected.
+
+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().
+
+
+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.
+
+
+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.
+
+
+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().
+
+
+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.
+
+
+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.
+
+
+Reading from clipboard 4:
+It is permissible to Unlock() the clipboard before calling FindData on the data message.
+
+
+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.
+
+
+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.
+
+
+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.
+
+
+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.
+
+
+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().
+
+
+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.
+
+
+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.
+
+
+Unlocking:
+Unlock() is used to unlock the BClipboard and allow other threads in the application to use it.
+
+
+Checking lock status:
+IsLocked() returns true if the BClipboard is locked, and false if it is not locked.
+
+
+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().
+
+
+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.
+
+
+
+
+
+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:
+
+This document describes the BCursor interface and some basics of how it is implemented.
+The document has the following sections:
+
+
+- BCursor Interface
+- BCursor Use Cases
+- BCursor Implementation
+
+
+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:
+
+
+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.
+
+Construction 2: The second BCursor constructor requires a BMessage as an archive, however BCursor does not currently support archiving. Do not use this constructor.
+
+Destruction: This releases all resources used by the BCursor.
+
+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.
+
+
+
+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