diff --git a/headers/os/app/Clipboard.h b/headers/os/app/Clipboard.h index 1f7d256ab5..f19d4d15b1 100644 --- a/headers/os/app/Clipboard.h +++ b/headers/os/app/Clipboard.h @@ -1,60 +1,31 @@ -//------------------------------------------------------------------------------ -// 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.h -// Author: Gabe Yoder (gyoder@stny.rr.com) -// Description: BClipboard provides an interface to a system-wide clipboard -// storage area. -//------------------------------------------------------------------------------ - +/* + * Copyright 2007, Haiku Inc. All Rights Reserved. + * Distributed under the terms of the MIT License. + * + * Author: + * Gabe Yoder, gyoder@stny.rr.com + */ #ifndef _CLIPBOARD_H #define _CLIPBOARD_H -// Standard Includes ----------------------------------------------------------- -// System Includes ------------------------------------------------------------- #include -#include #include +#include -// Project Includes ------------------------------------------------------------ - -// Local Includes -------------------------------------------------------------- - -// Local Defines --------------------------------------------------------------- - -// Globals --------------------------------------------------------------------- class BMessage; + enum { B_CLIPBOARD_CHANGED = 'CLCH' }; -// BClipboard class --------------------------------------------------------------- class BClipboard { -public: - BClipboard(const char *name, bool transient = false); - virtual ~BClipboard(); + public: + BClipboard(const char* name, bool transient = false); + virtual ~BClipboard(); - const char *Name() const; + const char* Name() const; uint32 LocalCount() const; uint32 SystemCount() const; @@ -64,42 +35,37 @@ public: bool Lock(); void Unlock(); bool IsLocked() const; - + status_t Clear(); status_t Commit(); + status_t Commit(bool failIfChanged); status_t Revert(); BMessenger DataSource() const; - BMessage *Data() const; + BMessage* Data() const; -/*----- Private or reserved -----------------------------------------*/ -private: - BClipboard(const BClipboard &); + private: + BClipboard(const BClipboard &); BClipboard &operator=(const BClipboard &); - virtual void _ReservedClipboard1(); - virtual void _ReservedClipboard2(); - virtual void _ReservedClipboard3(); + virtual void _ReservedClipboard1(); + virtual void _ReservedClipboard2(); + virtual void _ReservedClipboard3(); - bool AssertLocked() const; - status_t DownloadFromSystem(bool force = false); - status_t UploadToSystem(); + bool _AssertLocked() const; + status_t _DownloadFromSystem(bool force = false); + status_t _UploadToSystem(); uint32 _reserved0; - BMessage *fData; + BMessage* fData; BLocker fLock; BMessenger fClipHandler; BMessenger fDataSource; uint32 fCount; - char *fName; + char* fName; uint32 _reserved[4]; }; -//----- Global Clipboard ------------------------------------------------------- - -extern _IMPEXP_BE BClipboard *be_clipboard; - -//------------------------------------------------------------------------------ +extern BClipboard* be_clipboard; #endif // _CLIPBOARD_H - diff --git a/src/kits/app/Clipboard.cpp b/src/kits/app/Clipboard.cpp index 848366c59b..ac264e534e 100644 --- a/src/kits/app/Clipboard.cpp +++ b/src/kits/app/Clipboard.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2001-2005, Haiku. + * Copyright 2001-2007, Haiku. * Distributed under the terms of the MIT License. * * Authors: @@ -146,7 +146,7 @@ BClipboard::Lock() bool locked = fLock.Lock(); #ifndef RUN_WITHOUT_REGISTRAR - if (locked && DownloadFromSystem() != B_OK) { + if (locked && _DownloadFromSystem() != B_OK) { locked = false; fLock.Unlock(); } @@ -173,7 +173,7 @@ BClipboard::IsLocked() const status_t BClipboard::Clear() { - if (!AssertLocked()) + if (!_AssertLocked()) return B_NOT_ALLOWED; return fData->MakeEmpty(); @@ -183,22 +183,44 @@ BClipboard::Clear() status_t BClipboard::Commit() { - if (!AssertLocked()) + return Commit(false); +} + + +status_t +BClipboard::Commit(bool failIfChanged) +{ + if (!_AssertLocked()) return B_NOT_ALLOWED; - return UploadToSystem(); + status_t status = B_ERROR; + 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 + && message.AddInt32("count", fCount) == B_OK + && message.AddBool("fail if changed", failIfChanged) == B_OK) + status = fClipHandler.SendMessage(&message, &reply); + + if (status == B_OK) { + int32 count; + if (reply.FindInt32("count", &count) == B_OK) + fCount = count; + } + + return status; } status_t BClipboard::Revert() { - if (!AssertLocked()) + if (!_AssertLocked()) return B_NOT_ALLOWED; - + status_t status = fData->MakeEmpty(); if (status == B_OK) - status = DownloadFromSystem(); + status = _DownloadFromSystem(); return status; } @@ -214,7 +236,7 @@ BClipboard::DataSource() const BMessage * BClipboard::Data() const { - if (!AssertLocked()) + if (!_AssertLocked()) return NULL; return fData; @@ -243,7 +265,7 @@ void BClipboard::_ReservedClipboard3() {} bool -BClipboard::AssertLocked() const +BClipboard::_AssertLocked() const { // This function is for jumping to the debugger if not locked if (!fLock.IsLocked()) { @@ -255,7 +277,7 @@ BClipboard::AssertLocked() const status_t -BClipboard::DownloadFromSystem(bool force) +BClipboard::_DownloadFromSystem(bool force) { // Apparently, the force paramater was used in some sort of // optimization in R5. Currently, we ignore it. @@ -271,21 +293,6 @@ BClipboard::DownloadFromSystem(bool force) } -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 *)&fCount) == B_OK) { - return B_OK; - } - return B_ERROR; -} - - // #pragma mark - diff --git a/src/servers/registrar/ClipboardHandler.cpp b/src/servers/registrar/ClipboardHandler.cpp index a1efe18934..f134b4b062 100644 --- a/src/servers/registrar/ClipboardHandler.cpp +++ b/src/servers/registrar/ClipboardHandler.cpp @@ -1,13 +1,21 @@ -// ClipboardHandler.cpp +/* + * Copyright 2002-2007, Haiku, Inc. All Rights Reserved. + * Distributed under the terms of the MIT License. + * + * Authors: + * Ingo Weinhold, bonefish@users.sf.net + * Gabe Yoder + */ -#include -#include + +#include "Clipboard.h" +#include "ClipboardHandler.h" #include #include -#include "Clipboard.h" -#include "ClipboardHandler.h" +#include +#include using std::map; using std::string; @@ -151,9 +159,19 @@ ClipboardHandler::MessageReceived(BMessage *message) && message->FindMessage("data", &data) == B_OK) { Clipboard *clipboard = _GetClipboard(name); if (clipboard) { - clipboard->SetData(&data, source); - reply.AddInt32("count", clipboard->Count()); - result = B_OK; + int32 localCount; + bool failIfChanged; + if (message->FindInt32("count", &localCount) == B_OK + && message->FindBool("fail if changed", &failIfChanged) == B_OK + && failIfChanged + && localCount != clipboard->Count()) { + // atomic support + result = B_ERROR; + } else { + clipboard->SetData(&data, source); + result = reply.AddInt32("count", clipboard->Count()); + result = B_OK; + } } }