xref: /haiku/src/kits/app/Clipboard.cpp (revision 81f5654c124bf46fba0fd251f208e2d88d81e1ce)
1 //------------------------------------------------------------------------------
2 //	Copyright (c) 2001-2002, OpenBeOS
3 //
4 //	Permission is hereby granted, free of charge, to any person obtaining a
5 //	copy of this software and associated documentation files (the "Software"),
6 //	to deal in the Software without restriction, including without limitation
7 //	the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 //	and/or sell copies of the Software, and to permit persons to whom the
9 //	Software is furnished to do so, subject to the following conditions:
10 //
11 //	The above copyright notice and this permission notice shall be included in
12 //	all copies or substantial portions of the Software.
13 //
14 //	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 //	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 //	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 //	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 //	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 //	FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 //	DEALINGS IN THE SOFTWARE.
21 //
22 //	File Name:		Clipboard.cpp
23 //	Author:			Gabe Yoder (gyoder@stny.rr.com)
24 //	Description:	BClipboard provides an interface to a system-wide clipboard
25 //                  storage area.
26 //------------------------------------------------------------------------------
27 
28 // Standard Includes -----------------------------------------------------------
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 
33 // System Includes -------------------------------------------------------------
34 #include <Clipboard.h>
35 #include <Application.h>
36 #include <RegistrarDefs.h>
37 #include <RosterPrivate.h>
38 
39 // Project Includes ------------------------------------------------------------
40 
41 // Local Includes --------------------------------------------------------------
42 
43 // Local Defines ---------------------------------------------------------------
44 
45 // Globals ---------------------------------------------------------------------
46 
47 
48 //------------------------------------------------------------------------------
49 BClipboard::BClipboard(const char *name, bool transient)
50 {
51   if ( name )
52     fName = strdup(name);
53   else
54     fName = strdup("system");
55   fData = new BMessage();
56   fCount = 0;
57   fSystemCount = 0;
58 
59   BMessage message(B_REG_GET_CLIPBOARD_MESSENGER), reply;
60   if ( (BRoster::Private().SendTo(&message, &reply, false) == B_OK) &&
61        (reply.what == B_REG_SUCCESS) &&
62        (reply.FindMessenger("messenger",&fClipHandler) == B_OK) )
63   {
64     BMessage handlerMessage(B_REG_ADD_CLIPBOARD), handlerReply;
65     int32 result;
66     if ( (handlerMessage.AddString("name",fName) == B_OK) &&
67          (fClipHandler.SendMessage(&handlerMessage, &handlerReply) == B_OK) )
68       handlerReply.FindInt32("result",&result);
69   }
70 }
71 //------------------------------------------------------------------------------
72 BClipboard::~BClipboard()
73 {
74   free(fName);
75   delete fData;
76 }
77 //------------------------------------------------------------------------------
78 const char* BClipboard::Name() const
79 {
80   return (const char*)fName;
81 }
82 //------------------------------------------------------------------------------
83 uint32 BClipboard::LocalCount() const
84 {
85   /* fSystemCount contains the total number of writes to the clipboard.
86      fCount contains the number of writes to the clipboard done by this
87      BClipboard.
88   */
89   return fSystemCount;
90 }
91 //------------------------------------------------------------------------------
92 uint32 BClipboard::SystemCount() const
93 {
94   int32 val;
95   BMessage message(B_REG_GET_CLIPBOARD_COUNT), reply;
96   if ( (message.AddString("name",fName) == B_OK) &&
97        (fClipHandler.SendMessage(&message, &reply) == B_OK) &&
98        (reply.FindInt32("count",&val) == B_OK) )
99     return (uint32)val;
100 
101   return 0;
102 }
103 //------------------------------------------------------------------------------
104 status_t BClipboard::StartWatching(BMessenger target)
105 {
106   BMessage message(B_REG_CLIPBOARD_START_WATCHING), reply;
107   if ( (message.AddString("name",fName) == B_OK) &&
108        (message.AddMessenger("target", target ) == B_OK) &&
109        (fClipHandler.SendMessage(&message, &reply) == B_OK) )
110   {
111     int32 result;
112     reply.FindInt32("result",&result);
113     return result;
114   }
115   return B_ERROR;
116 }
117 //------------------------------------------------------------------------------
118 status_t BClipboard::StopWatching(BMessenger target)
119 {
120   BMessage message(B_REG_CLIPBOARD_STOP_WATCHING), reply;
121   if ( (message.AddString("name",fName) == B_OK) &&
122        (message.AddMessenger("target", target ) == B_OK) &&
123        (fClipHandler.SendMessage(&message, &reply) == B_OK) )
124   {
125     int32 result;
126     reply.FindInt32("result",&result);
127     return result;
128   }
129   return B_ERROR;
130 }
131 //------------------------------------------------------------------------------
132 bool BClipboard::Lock()
133 {
134   /* Will this work correctly if clipboard is deleted while still waiting on
135      fLock.Lock() ? */
136   bool retVal;
137   retVal = fLock.Lock();
138   if ( retVal  &&
139       (DownloadFromSystem() != B_OK) )
140   {
141     retVal = false;
142     fLock.Unlock();
143   }
144 
145   return retVal;
146 }
147 //------------------------------------------------------------------------------
148 void BClipboard::Unlock()
149 {
150   fLock.Unlock();
151 }
152 //------------------------------------------------------------------------------
153 bool BClipboard::IsLocked() const
154 {
155   return fLock.IsLocked();
156 }
157 //------------------------------------------------------------------------------
158 status_t BClipboard::Clear()
159 {
160   if ( AssertLocked() &&
161        (fData->MakeEmpty() == B_OK) )
162     return B_OK;
163   return B_ERROR;
164 }
165 //------------------------------------------------------------------------------
166 status_t BClipboard::Commit()
167 {
168   if ( AssertLocked() &&
169        (UploadToSystem() == B_OK) )
170     return B_OK;
171   return B_ERROR;
172 }
173 //------------------------------------------------------------------------------
174 status_t BClipboard::Revert()
175 {
176   if ( AssertLocked() &&
177        (fData->MakeEmpty() == B_OK) &&
178        (DownloadFromSystem() == B_OK) )
179     return B_OK;
180   return B_ERROR;
181 }
182 //------------------------------------------------------------------------------
183 BMessenger BClipboard::DataSource() const
184 {
185   return fDataSource;
186 }
187 //------------------------------------------------------------------------------
188 BMessage* BClipboard::Data() const
189 {
190   if ( IsLocked() )
191     return fData;
192   return NULL;
193 }
194 //------------------------------------------------------------------------------
195 BClipboard::BClipboard(const BClipboard &)
196 {
197   /* This is private, and I don't use it, so I'm not going to implement it */
198 }
199 //------------------------------------------------------------------------------
200 BClipboard & BClipboard::operator=(const BClipboard &)
201 {
202   /* This is private, and I don't use it, so I'm not going to implement it */
203 	return *this;
204 }
205 //------------------------------------------------------------------------------
206 void BClipboard::_ReservedClipboard1()
207 {
208 }
209 //------------------------------------------------------------------------------
210 void BClipboard::_ReservedClipboard2()
211 {
212 }
213 //------------------------------------------------------------------------------
214 void BClipboard::_ReservedClipboard3()
215 {
216 }
217 //------------------------------------------------------------------------------
218 bool BClipboard::AssertLocked() const
219 {
220 	// This function is for jumping to the debugger if not locked
221 	if(!fLock.IsLocked())
222 	{
223 		debugger("The clipboard must be locked before proceeding.");
224 		return false;
225 	}
226 	return true;
227 }
228 //------------------------------------------------------------------------------
229 status_t BClipboard::DownloadFromSystem(bool force)
230 {
231 	// Apparently, the force paramater was used in some sort of
232 	// optimization in R5. Currently, we ignore it.
233   BMessage message(B_REG_DOWNLOAD_CLIPBOARD), reply;
234   if ( (message.AddString("name",fName) == B_OK) &&
235        (fClipHandler.SendMessage(&message, &reply) == B_OK) &&
236        (reply.FindMessage("data",fData) == B_OK) &&
237        (reply.FindMessenger("data source",&fDataSource) == B_OK) &&
238        (reply.FindInt32("count",(int32 *)(&fSystemCount)) == B_OK) )
239     return B_OK;
240   return B_ERROR;
241 }
242 //------------------------------------------------------------------------------
243 status_t BClipboard::UploadToSystem()
244 {
245   BMessage message(B_REG_UPLOAD_CLIPBOARD), reply;
246   if ( (message.AddString("name",fName) == B_OK) &&
247        (message.AddMessage("data",fData) == B_OK) &&
248        (message.AddMessenger("data source", be_app_messenger ) == B_OK) &&
249        (fClipHandler.SendMessage(&message, &reply) == B_OK) &&
250        (reply.FindInt32("count",(int32 *)(&fSystemCount)) == B_OK) )
251   {
252     fCount++;
253     return B_OK;
254   }
255   return B_ERROR;
256 }
257 //------------------------------------------------------------------------------
258 
259 
260