Bug 470455 - test_database_sync_embed_visits.js leaks, r=sdwilsh
[wine-gecko.git] / widget / src / beos / nsClipboard.cpp
blobb2427728ca48bc585a966cc871beacec4f45c239
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
15 * The Original Code is mozilla.org code.
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1998
20 * the Initial Developer. All Rights Reserved.
22 * Contributor(s):
23 * Pierre Phaneuf <pp@ludusdesign.com>
24 * Takashi Toyoshima <toyoshim@be-in.org>
26 * Alternatively, the contents of this file may be used under the terms of
27 * either the GNU General Public License Version 2 or later (the "GPL"), or
28 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 * in which case the provisions of the GPL or the LGPL are applicable instead
30 * of those above. If you wish to allow use of your version of this file only
31 * under the terms of either the GPL or the LGPL, and not to allow others to
32 * use your version of this file under the terms of the MPL, indicate your
33 * decision by deleting the provisions above and replace them with the notice
34 * and other provisions required by the GPL or the LGPL. If you do not delete
35 * the provisions above, a recipient may use your version of this file under
36 * the terms of any one of the MPL, the GPL or the LGPL.
38 * ***** END LICENSE BLOCK ***** */
40 #include "nsClipboard.h"
41 #include "nsCOMPtr.h"
42 #include "nsITransferable.h"
43 #include "nsWidgetsCID.h"
44 #include "nsXPIDLString.h"
45 #include "nsPrimitiveHelpers.h"
46 #include "nsXPCOM.h"
47 #include "nsISupportsPrimitives.h"
48 #include "nsString.h"
50 #include <View.h>
51 #include <Clipboard.h>
52 #include <Message.h>
54 // The class statics:
55 BView *nsClipboard::sView = 0;
57 #if defined(DEBUG_akkana) || defined(DEBUG_mcafee) || defined(DEBUG_toyoshim)
58 # define DEBUG_CLIPBOARD
59 #endif
62 //-------------------------------------------------------------------------
64 // nsClipboard constructor
66 //-------------------------------------------------------------------------
67 nsClipboard::nsClipboard() : nsBaseClipboard()
69 #ifdef DEBUG_CLIPBOARD
70 printf(" nsClipboard::nsClipboard()\n");
71 #endif /* DEBUG_CLIPBOARD */
73 mIgnoreEmptyNotification = PR_FALSE;
74 mClipboardOwner = nsnull;
75 mTransferable = nsnull;
78 //-------------------------------------------------------------------------
80 // nsClipboard destructor
82 //-------------------------------------------------------------------------
83 nsClipboard::~nsClipboard()
85 #ifdef DEBUG_CLIPBOARD
86 printf(" nsClipboard::~nsClipboard()\n");
87 #endif /* DEBUG_CLIPBOARD */
90 void nsClipboard::SetTopLevelView(BView *v)
92 // Don't set up any more event handlers if we're being called twice
93 // for the same toplevel widget
94 if (sView == v)
95 return;
97 if (sView != 0 && sView->Window() != 0)
98 return;
100 if(v == 0 || v->Window() == 0)
102 #ifdef DEBUG_CLIPBOARD
103 printf(" nsClipboard::SetTopLevelView: widget passed in is null or has no window!\n");
104 #endif /* DEBUG_CLIPBOARD */
105 return;
108 #ifdef DEBUG_CLIPBOARD
109 printf(" nsClipboard::SetTopLevelView\n");
110 #endif /* DEBUG_CLIPBOARD */
114 // The copy routine
116 NS_IMETHODIMP nsClipboard::SetNativeClipboardData(PRInt32 aWhichClipboard)
118 mIgnoreEmptyNotification = PR_TRUE;
120 #ifdef DEBUG_CLIPBOARD
121 printf(" nsClipboard::SetNativeClipboardData()\n");
122 #endif /* DEBUG_CLIPBOARD */
124 // make sure we have a good transferable
125 if (nsnull == mTransferable) {
126 #ifdef DEBUG_CLIPBOARD
127 printf(" SetNativeClipboardData: no transferable!\n");
128 #endif /* DEBUG_CLIPBOARD */
129 return NS_ERROR_FAILURE;
132 // lock the native clipboard
133 if (!be_clipboard->Lock())
134 return NS_ERROR_FAILURE;
136 // clear the native clipboard
137 nsresult rv = NS_OK;
138 if (B_OK == be_clipboard->Clear()) {
139 // set data to the native clipboard
140 if (BMessage *msg = be_clipboard->Data()) {
141 // Get the transferable list of data flavors
142 nsCOMPtr<nsISupportsArray> dfList;
143 mTransferable->FlavorsTransferableCanExport(getter_AddRefs(dfList));
145 // Walk through flavors that contain data and register them
146 // into the BMessage as supported flavors
147 PRUint32 i;
148 PRUint32 cnt;
149 dfList->Count(&cnt);
150 for (i = 0; i < cnt && rv == NS_OK; i++) {
151 nsCOMPtr<nsISupports> genericFlavor;
152 dfList->GetElementAt(i, getter_AddRefs(genericFlavor));
153 nsCOMPtr<nsISupportsCString> currentFlavor (do_QueryInterface(genericFlavor));
154 if (currentFlavor) {
155 nsXPIDLCString flavorStr;
156 currentFlavor->ToString(getter_Copies(flavorStr));
158 #ifdef DEBUG_CLIPBOARD
159 printf("nsClipboard: %d/%d = %s\n", i, cnt, (const char *)flavorStr);
160 #endif /* DEBUG_CLIPBOARD */
161 if (0 == strncmp(flavorStr, "text/", 5)) {
162 // [NS] text/ * => [Be] text/ *
163 void *data = nsnull;
164 PRUint32 dataSize = 0;
165 nsCOMPtr<nsISupports> genericDataWrapper;
166 rv = mTransferable->GetTransferData(flavorStr, getter_AddRefs(genericDataWrapper), &dataSize);
167 nsPrimitiveHelpers::CreateDataFromPrimitive(flavorStr, genericDataWrapper, &data, dataSize);
168 #ifdef DEBUG_CLIPBOARD
169 if (NS_FAILED(rv))
170 printf("nsClipboard: Error getting data from transferable\n");
171 #endif /* DEBUG_CLIPBOARD */
172 if (dataSize && data != nsnull) {
173 NS_ConvertUTF16toUTF8 cv((const PRUnichar *)data, (PRUint32)dataSize / 2);
174 const char *utf8Str = cv.get();
175 uint32 utf8Len = strlen(utf8Str);
176 #ifdef DEBUG_CLIPBOARD
177 if (0 == strcmp(flavorStr, kUnicodeMime))
178 printf(" => [%s]%s\n", kTextMime, utf8Str);
179 else
180 printf(" => [%s]%s\n", (const char *)flavorStr, utf8Str);
181 #endif /* DEBUG_CLIPBOARD */
182 status_t rc;
183 if (0 == strcmp(flavorStr, kUnicodeMime)) {
184 // [NS] text/unicode => [Be] text/plain
185 rc = msg->AddData(kTextMime, B_MIME_TYPE, (void *)utf8Str, utf8Len);
186 } else {
187 // [NS] text/ * => [Be] text/ *
188 rc = msg->AddData((const char *)flavorStr, B_MIME_TYPE, (void *)utf8Str, utf8Len);
190 if (rc != B_OK)
191 rv = NS_ERROR_FAILURE;
192 } else {
193 #ifdef DEBUG_CLIPBOARD
194 printf("nsClipboard: Error null data from transferable\n");
195 #endif /* DEBUG_CLIPBOARD */
196 // not fatal. force to continue...
197 rv = NS_OK;
199 } else {
200 // [NS] * / * => [Be] * / *
201 void *data = nsnull;
202 PRUint32 dataSize = 0;
203 nsCOMPtr<nsISupports> genericDataWrapper;
204 rv = mTransferable->GetTransferData(flavorStr, getter_AddRefs(genericDataWrapper), &dataSize);
205 nsPrimitiveHelpers::CreateDataFromPrimitive(flavorStr, genericDataWrapper, &data, dataSize);
206 #ifdef DEBUG_CLIPBOARD
207 if (NS_FAILED(rv))
208 printf("nsClipboard: Error getting data from transferable\n");
209 #endif /* DEBUG_CLIPBOARD */
210 if (dataSize && data != nsnull) {
211 #ifdef DEBUG_CLIPBOARD
212 printf("[%s](binary)\n", (const char *)flavorStr);
213 #endif /* DEBUG_CLIPBOARD */
214 if (B_OK != msg->AddData((const char *)flavorStr, B_MIME_TYPE, data, dataSize))
215 rv = NS_ERROR_FAILURE;
218 } else {
219 #ifdef DEBUG_CLIPBOARD
220 printf("nsClipboard: Error getting flavor\n");
221 #endif /* DEBUG_CLIPBOARD */
222 rv = NS_ERROR_FAILURE;
224 } /* for */
225 } else {
226 rv = NS_ERROR_FAILURE;
228 } else {
229 rv = NS_ERROR_FAILURE;
231 if (B_OK != be_clipboard->Commit())
232 rv = NS_ERROR_FAILURE;
233 be_clipboard->Unlock();
235 mIgnoreEmptyNotification = PR_FALSE;
237 return rv;
242 // The blocking Paste routine
244 NS_IMETHODIMP
245 nsClipboard::GetNativeClipboardData(nsITransferable * aTransferable, PRInt32 aWhichClipboard )
247 #ifdef DEBUG_CLIPBOARD
248 printf(" nsClipboard::GetNativeClipboardData()\n");
249 #endif /* DEBUG_CLIPBOARD */
251 // make sure we have a good transferable
252 if (nsnull == aTransferable) {
253 printf(" GetNativeClipboardData: Transferable is null!\n");
254 return NS_ERROR_FAILURE;
257 // get flavor list
258 nsresult rv;
259 nsCOMPtr<nsISupportsArray> flavorList;
260 rv = aTransferable->FlavorsTransferableCanImport(getter_AddRefs(flavorList));
261 if (NS_FAILED(rv))
262 return NS_ERROR_FAILURE;
264 // get native clipboard data
265 if (!be_clipboard->Lock())
266 return NS_ERROR_FAILURE;
268 BMessage *msg = be_clipboard->Data();
269 if (!msg)
270 return NS_ERROR_FAILURE;
271 #ifdef DEBUG_CLIPBOARD
272 msg->PrintToStream();
273 #endif /* DEBUG_CLIPBOARD */
275 PRUint32 cnt;
276 flavorList->Count(&cnt);
277 for (PRUint32 i = 0; i < cnt; i++) {
278 nsCOMPtr<nsISupports> genericFlavor;
279 flavorList->GetElementAt(i, getter_AddRefs(genericFlavor));
280 nsCOMPtr<nsISupportsCString> currentFlavor(do_QueryInterface(genericFlavor));
281 if (currentFlavor) {
282 nsXPIDLCString flavorStr;
283 currentFlavor->ToString(getter_Copies(flavorStr));
285 #ifdef DEBUG_CLIPBOARD
286 printf("nsClipboard: %d/%d = %s\n", i, cnt, (const char *)flavorStr);
287 #endif /* DEBUG_CLIPBOARD */
288 const void *data;
289 ssize_t size;
290 if (0 == strncmp(flavorStr, "text/", 5)) {
291 // [Be] text/ * => [NS] text/ *
292 status_t rc;
293 if (0 == strcmp(flavorStr, kUnicodeMime))
294 rc = msg->FindData(kTextMime, B_MIME_TYPE, &data, &size);
295 else
296 rc = msg->FindData(flavorStr, B_MIME_TYPE, &data, &size);
297 if (rc != B_OK || !data || !size) {
298 #ifdef DEBUG_CLIPBOARD
299 printf("nsClipboard: not found in BMessage\n");
300 #endif /* DEBUG_CLIPBOARD */
301 } else {
302 NS_ConvertUTF8toUTF16 ucs2Str((const char *)data, (PRUint32)size);
303 nsCOMPtr<nsISupports> genericDataWrapper;
304 nsPrimitiveHelpers::CreatePrimitiveForData(flavorStr, (void *)ucs2Str.get(), ucs2Str.Length() * 2, getter_AddRefs(genericDataWrapper));
305 rv = aTransferable->SetTransferData(flavorStr, genericDataWrapper, ucs2Str.Length() * 2);
307 } else {
308 // [Be] * / * => [NS] * / *
309 if (B_OK != msg->FindData(flavorStr, B_MIME_TYPE, &data, &size)) {
310 #ifdef DEBUG_CLIPBOARD
311 printf("nsClipboard: not found in BMessage\n");
312 #endif /* DEBUG_CLIPBOARD */
313 } else {
314 nsCOMPtr<nsISupports> genericDataWrapper;
315 nsPrimitiveHelpers::CreatePrimitiveForData(flavorStr, (void *)data, (PRUint32)size, getter_AddRefs(genericDataWrapper));
316 rv = aTransferable->SetTransferData(flavorStr, genericDataWrapper, size);
319 #ifdef DEBUG_CLIPBOARD
320 if (NS_FAILED(rv))
321 printf("nsClipboard: Error SetTransferData\n");
322 #endif /* DEBUG_CLIPBOARD */
323 } else {
324 rv = NS_ERROR_FAILURE;
325 #ifdef DEBUG_CLIPBOARD
326 printf("nsClipboard: Error gerring flavor");
327 #endif /* DEBUG_CLIPBOARD */
329 if (rv != NS_OK)
330 break;
331 } /* for */
333 be_clipboard->Unlock();
335 return rv;