diff --git a/widget/src/beos/nsClipboard.cpp b/widget/src/beos/nsClipboard.cpp index 106b7026b39..31bc0cae36c 100644 --- a/widget/src/beos/nsClipboard.cpp +++ b/widget/src/beos/nsClipboard.cpp @@ -19,21 +19,17 @@ * * Contributor(s): * Pierre Phaneuf + * Takashi Toyoshima */ #include "nsClipboard.h" - #include "nsCOMPtr.h" - -#include "nsIClipboardOwner.h" -#include "nsITransferable.h" // kTextMime - -#include "nsIWidget.h" -#include "nsIServiceManager.h" +#include "nsITransferable.h" #include "nsWidgetsCID.h" #include "nsXPIDLString.h" #include "nsPrimitiveHelpers.h" #include "nsISupportsPrimitives.h" +#include "nsString.h" #include #include @@ -42,13 +38,8 @@ // The class statics: BView *nsClipboard::sView = 0; -NS_IMPL_ADDREF_INHERITED(nsClipboard, nsBaseClipboard) -NS_IMPL_RELEASE_INHERITED(nsClipboard, nsBaseClipboard) - -static NS_DEFINE_CID(kCClipboardCID, NS_CLIPBOARD_CID); - -#if defined(DEBUG_akkana) || defined(DEBUG_mcafee) -#define DEBUG_CLIPBOARD +#if defined(DEBUG_akkana) || defined(DEBUG_mcafee) || defined(DEBUG_toyoshim) +# define DEBUG_CLIPBOARD #endif @@ -67,8 +58,6 @@ nsClipboard::nsClipboard() : nsBaseClipboard() mIgnoreEmptyNotification = PR_FALSE; mClipboardOwner = nsnull; mTransferable = nsnull; -// mSelectionData.data = nsnull; -// mSelectionData.length = 0; } //------------------------------------------------------------------------- @@ -81,41 +70,8 @@ nsClipboard::~nsClipboard() #ifdef DEBUG_CLIPBOARD printf(" nsClipboard::~nsClipboard()\n"); #endif /* DEBUG_CLIPBOARD */ - -// // Remove all our event handlers: -// if (sView && -// gdk_selection_owner_get (GDK_SELECTION_PRIMARY) == sWidget->window) -// gtk_selection_remove_all(sWidget); -// -// // free the selection data, if any -// if (mSelectionData.data != nsnull) -// g_free(mSelectionData.data); } -/** - * @param aIID The name of the class implementing the method - * @param _classiiddef The name of the #define symbol that defines the IID - * for the class (e.g. NS_ISUPPORTS_IID) - * -*/ -nsresult nsClipboard::QueryInterface(const nsIID& aIID, void** aInstancePtr) -{ - if (NULL == aInstancePtr) { - return NS_ERROR_NULL_POINTER; - } - - nsresult rv = NS_NOINTERFACE; - - if (aIID.Equals(NS_GET_IID(nsIClipboard))) { - *aInstancePtr = (void*) ((nsIClipboard*)this); - NS_ADDREF_THIS(); - return NS_OK; - } - - return rv; -} - - void nsClipboard::SetTopLevelView(BView *v) { // Don't set up any more event handlers if we're being called twice @@ -137,66 +93,11 @@ void nsClipboard::SetTopLevelView(BView *v) #ifdef DEBUG_CLIPBOARD printf(" nsClipboard::SetTopLevelView\n"); #endif /* DEBUG_CLIPBOARD */ - -// // If we're changing from one widget to another -// // (shouldn't generally happen), clear the old event handlers: -// if (sView && -// gdk_selection_owner_get (GDK_SELECTION_PRIMARY) == sWidget->window) -// gtk_selection_remove_all(sWidget); -// -// sWidget = w; -// -// // Get the clipboard from the service manager. -// nsresult rv; -// NS_WITH_SERVICE(nsIClipboard, clipboard, kCClipboardCID, &rv); -// -// if (!NS_SUCCEEDED(rv)) { -// printf("Couldn't get clipboard service!\n"); -// return; -// } -// -// // Handle selection requests if we called gtk_selection_add_target: -// gtk_signal_connect(GTK_OBJECT(sWidget), "selection_get", -// GTK_SIGNAL_FUNC(nsClipboard::SelectionGetCB), -// clipboard); -// -// // When someone else takes the selection away: -// gtk_signal_connect(GTK_OBJECT(sWidget), "selection_clear_event", -// GTK_SIGNAL_FUNC(nsClipboard::SelectionClearCB), -// clipboard); -// -// // Set up the paste handler: -// gtk_signal_connect(GTK_OBJECT(sWidget), "selection_received", -// GTK_SIGNAL_FUNC(nsClipboard::SelectionReceivedCB), -// clipboard); -// -//#if 0 -// // Handle selection requests if we called gtk_selection_add_targets: -// gtk_signal_connect(GTK_OBJECT(sWidget), "selection_request_event", -// GTK_SIGNAL_FUNC(nsClipboard::SelectionRequestCB), -// clipboard); -// -// // Watch this, experimenting with Gtk :-) -// gtk_signal_connect(GTK_OBJECT(sWidget), "selection_notify_event", -// GTK_SIGNAL_FUNC(nsClipboard::SelectionNotifyCB), -// clipboard); -//#endif -// -// // Hmm, sometimes we need this, sometimes not. I'm not clear why. -// // See also long comment above on why we don't register a whole target list. -// -// // Register all the target types we handle: -// gtk_selection_add_target(sWidget, -// GDK_SELECTION_PRIMARY, -// GDK_SELECTION_TYPE_STRING, -// GDK_SELECTION_TYPE_STRING); } - -/** - * - * - */ +// +// The copy routine +// NS_IMETHODIMP nsClipboard::SetNativeClipboardData(PRInt32 aWhichClipboard) { mIgnoreEmptyNotification = PR_TRUE; @@ -218,11 +119,10 @@ NS_IMETHODIMP nsClipboard::SetNativeClipboardData(PRInt32 aWhichClipboard) return NS_ERROR_FAILURE; // clear the native clipboard - nsresult rv = NS_ERROR_FAILURE; + nsresult rv = NS_OK; if (B_OK == be_clipboard->Clear()) { // set data to the native clipboard - BMessage *msg = be_clipboard->Data(); - if (NULL != msg) { + if (BMessage *msg = be_clipboard->Data()) { // Get the transferable list of data flavors nsCOMPtr dfList; mTransferable->FlavorsTransferableCanExport(getter_AddRefs(dfList)); @@ -232,42 +132,86 @@ NS_IMETHODIMP nsClipboard::SetNativeClipboardData(PRInt32 aWhichClipboard) PRUint32 i; PRUint32 cnt; dfList->Count(&cnt); - for (i = 0; i < cnt; i++) { - nsCOMPtr genericFlavor; - dfList->GetElementAt(i, getter_AddRefs(genericFlavor)); - nsCOMPtr currentFlavor ( do_QueryInterface(genericFlavor)); - if (NULL != currentFlavor) { - nsXPIDLCString flavorStr; - currentFlavor->ToString(getter_Copies(flavorStr)); + for (i = 0; i < cnt && rv == NS_OK; i++) { + nsCOMPtr genericFlavor; + dfList->GetElementAt(i, getter_AddRefs(genericFlavor)); + nsCOMPtr currentFlavor (do_QueryInterface(genericFlavor)); + if (currentFlavor) { + nsXPIDLCString flavorStr; + currentFlavor->ToString(getter_Copies(flavorStr)); #ifdef DEBUG_CLIPBOARD - printf("nsClipboard: %d = %s\n", i, (const char *)flavorStr); + printf("nsClipboard: %d/%d = %s\n", i, cnt, (const char *)flavorStr); #endif /* DEBUG_CLIPBOARD */ - if (0 == strcmp(flavorStr, kUnicodeMime)) { - void *data = nsnull; - PRUint32 dataSize = 0; - nsCOMPtr genericDataWrapper; - rv = mTransferable->GetTransferData(flavorStr, getter_AddRefs(genericDataWrapper), &dataSize); + if (0 == strncmp(flavorStr, "text/", 5)) { + // [NS] text/ * => [Be] text/ * + void *data = nsnull; + PRUint32 dataSize = 0; + nsCOMPtr genericDataWrapper; + rv = mTransferable->GetTransferData(flavorStr, getter_AddRefs(genericDataWrapper), &dataSize); nsPrimitiveHelpers::CreateDataFromPrimitive(flavorStr, genericDataWrapper, &data, dataSize); #ifdef DEBUG_CLIPBOARD - if (NS_FAILED(rv)) - printf("nsClipboard: Error getting data from transferable\n"); + if (NS_FAILED(rv)) + printf("nsClipboard: Error getting data from transferable\n"); #endif /* DEBUG_CLIPBOARD */ - if ((0 != dataSize) && (NULL != data)) { - const char *utf8Str = NS_ConvertUCS2toUTF8((const PRUnichar*)data, (PRUint32)dataSize); - uint32 utf8Len = strlen(utf8Str); - if (B_OK == msg->AddData(kTextMime, B_MIME_TYPE, (void *)utf8Str, utf8Len)) - rv = NS_OK; - } + if (dataSize && data != nsnull) { + NS_ConvertUCS2toUTF8 cv((const PRUnichar *)data, (PRUint32)dataSize / 2); + const char *utf8Str = (const char *)cv; + uint32 utf8Len = strlen(utf8Str); #ifdef DEBUG_CLIPBOARD - else { - printf("nsClipboard: Error null data from transferable\n"); - } + if (0 == strcmp(flavorStr, kUnicodeMime)) + printf(" => [%s]%s\n", kTextMime, utf8Str); + else + printf(" => [%s]%s\n", (const char *)flavorStr, utf8Str); #endif /* DEBUG_CLIPBOARD */ - } - } - } + status_t rc; + if (0 == strcmp(flavorStr, kUnicodeMime)) { + // [NS] text/unicode => [Be] text/plain + rc = msg->AddData(kTextMime, B_MIME_TYPE, (void *)utf8Str, utf8Len); + } else { + // [NS] text/ * => [Be] text/ * + rc = msg->AddData((const char *)flavorStr, B_MIME_TYPE, (void *)utf8Str, utf8Len); + } + if (rc != B_OK) + rv = NS_ERROR_FAILURE; + } else { +#ifdef DEBUG_CLIPBOARD + printf("nsClipboard: Error null data from transferable\n"); +#endif /* DEBUG_CLIPBOARD */ + // not fatal. force to continue... + rv = NS_OK; + } + } else { + // [NS] * / * => [Be] * / * + void *data = nsnull; + PRUint32 dataSize = 0; + nsCOMPtr genericDataWrapper; + rv = mTransferable->GetTransferData(flavorStr, getter_AddRefs(genericDataWrapper), &dataSize); + nsPrimitiveHelpers::CreateDataFromPrimitive(flavorStr, genericDataWrapper, &data, dataSize); +#ifdef DEBUG_CLIPBOARD + if (NS_FAILED(rv)) + printf("nsClipboard: Error getting data from transferable\n"); +#endif /* DEBUG_CLIPBOARD */ + if (dataSize && data != nsnull) { +#ifdef DEBUG_CLIPBOARD + printf("[%s](binary)\n", (const char *)flavorStr); +#endif /* DEBUG_CLIPBOARD */ + if (B_OK != msg->AddData((const char *)flavorStr, B_MIME_TYPE, data, dataSize)) + rv = NS_ERROR_FAILURE; + } + } + } else { +#ifdef DEBUG_CLIPBOARD + printf("nsClipboard: Error getting flavor\n"); +#endif /* DEBUG_CLIPBOARD */ + rv = NS_ERROR_FAILURE; + } + } /* for */ + } else { + rv = NS_ERROR_FAILURE; } + } else { + rv = NS_ERROR_FAILURE; } if (B_OK != be_clipboard->Commit()) rv = NS_ERROR_FAILURE; @@ -295,99 +239,90 @@ nsClipboard::GetNativeClipboardData(nsITransferable * aTransferable, PRInt32 aWh return NS_ERROR_FAILURE; } + // get flavor list + nsresult rv; + nsCOMPtr flavorList; + rv = aTransferable->FlavorsTransferableCanImport(getter_AddRefs(flavorList)); + if (NS_FAILED(rv)) + return NS_ERROR_FAILURE; + // get native clipboard data if (!be_clipboard->Lock()) return NS_ERROR_FAILURE; BMessage *msg = be_clipboard->Data(); - nsresult rv = NS_ERROR_FAILURE; + if (!msg) + return NS_ERROR_FAILURE; +#ifdef DEBUG_CLIPBOARD + msg->PrintToStream(); +#endif /* DEBUG_CLIPBOARD */ - if (NULL != msg) { - const void *data; - ssize_t size; - status_t rc = msg->FindData(kTextMime, B_MIME_TYPE, &data, &size); - if ((B_OK == rc) && (NULL != data) && (0 != size)) { - nsString ucs2Str = NS_ConvertUTF8toUCS2((const char*)data, (PRUint32)size); - nsCOMPtr genericDataWrapper; - nsXPIDLCString mime; - mime = kUnicodeMime; - nsPrimitiveHelpers::CreatePrimitiveForData(mime, (void*)ucs2Str.GetUnicode(), ucs2Str.Length() * 2, getter_AddRefs(genericDataWrapper)); - aTransferable->SetTransferData(mime, genericDataWrapper, ucs2Str.Length() * 2); - rv = NS_OK; + PRUint32 cnt; + flavorList->Count(&cnt); + for (PRUint32 i = 0; i < cnt; i++) { + nsCOMPtr genericFlavor; + flavorList->GetElementAt(i, getter_AddRefs(genericFlavor)); + nsCOMPtr currentFlavor(do_QueryInterface(genericFlavor)); + if (currentFlavor) { + nsXPIDLCString flavorStr; + currentFlavor->ToString(getter_Copies(flavorStr)); + +#ifdef DEBUG_CLIPBOARD + printf("nsClipboard: %d/%d = %s\n", i, cnt, (const char *)flavorStr); +#endif /* DEBUG_CLIPBOARD */ + const void *data; + ssize_t size; + if (0 == strncmp(flavorStr, "text/", 5)) { + // [Be] text/ * => [NS] text/ * + status_t rc; + if (0 == strcmp(flavorStr, kUnicodeMime)) + rc = msg->FindData(kTextMime, B_MIME_TYPE, &data, &size); + else + rc = msg->FindData(flavorStr, B_MIME_TYPE, &data, &size); + if (rc != B_OK || !data || !size) { +#ifdef DEBUG_CLIPBOARD + printf("nsClipboard: not found in BMessage\n"); +#endif /* DEBUG_CLIPBOARD */ + } else { + nsString ucs2Str = NS_ConvertUTF8toUCS2((const char *)data, (PRUint32)size); + nsCOMPtr genericDataWrapper; + nsPrimitiveHelpers::CreatePrimitiveForData(flavorStr, (void *)ucs2Str.GetUnicode(), ucs2Str.Length() * 2, getter_AddRefs(genericDataWrapper)); + rv = aTransferable->SetTransferData(flavorStr, genericDataWrapper, ucs2Str.Length() * 2); + } + } else { + // [Be] * / * => [NS] * / * + if (B_OK != msg->FindData(flavorStr, B_MIME_TYPE, &data, &size)) { +#ifdef DEBUG_CLIPBOARD + printf("nsClipboard: not found in BMessage\n"); +#endif /* DEBUG_CLIPBOARD */ + } else { + nsCOMPtr genericDataWrapper; + nsPrimitiveHelpers::CreatePrimitiveForData(flavorStr, (void *)data, (PRUint32)size, getter_AddRefs(genericDataWrapper)); + rv = aTransferable->SetTransferData(flavorStr, genericDataWrapper, size); + } + } +#ifdef DEBUG_CLIPBOARD + if (NS_FAILED(rv)) + printf("nsClipboard: Error SetTransferData\n"); +#endif /* DEBUG_CLIPBOARD */ + } else { + rv = NS_ERROR_FAILURE; +#ifdef DEBUG_CLIPBOARD + printf("nsClipboard: Error gerring flavor"); +#endif /* DEBUG_CLIPBOARD */ } - } + if (rv != NS_OK) + break; + } /* for */ + be_clipboard->Unlock(); return rv; } // -// Called when the data from a paste comes in: -// -//void -//nsClipboard::SelectionReceivedCB (GtkWidget *aWidget, -// GtkSelectionData *aSelectionData, -// gpointer aData) -//{ -//#ifdef DEBUG_CLIPBOARD -// printf(" nsClipboard::SelectionReceivedCB\n"); -//#endif /* DEBUG_CLIPBOARD */ +// No-op. // -// // ARGHH! GTK doesn't pass the arg to the callback, so we can't -// // get "this" back! Until we solve this, get it from the service mgr: -// nsresult rv; -// NS_WITH_SERVICE(nsIClipboard, iclipboard, kCClipboardCID, &rv); -// -// if (NS_FAILED(rv)) { -// printf("Couldn't get clipboard service!\n"); -// return; -// } -// nsClipboard* clipboard = (nsClipboard*)iclipboard; -// if (!clipboard) { -// printf("couldn't convert nsIClipboard to nsClipboard\n"); -// return; -// } -// -// clipboard->SelectionReceiver(aWidget, aSelectionData); -//} -// -//void -//nsClipboard::SelectionReceiver (GtkWidget *aWidget, -// GtkSelectionData *aSelectionData) -//{ -// mBlocking = PR_FALSE; -// -// if (aSelectionData->length < 0) -// { -// printf("Error retrieving selection: length was %d\n", -// aSelectionData->length); -// return; -// } -// -// switch (aSelectionData->type) -// { -// case GDK_SELECTION_TYPE_STRING: -// mSelectionData = *aSelectionData; -// mSelectionData.data = g_new(guchar, aSelectionData->length + 1); -// memcpy(mSelectionData.data, -// aSelectionData->data, aSelectionData->length); -// // Null terminate in case anyone cares, -// // and so we can print the string for debugging: -// mSelectionData.data[aSelectionData->length] = '\0'; -// mSelectionData.length = aSelectionData->length; -// return; -// -// default: -// printf("Can't convert type %s (%ld) to string\n", -// gdk_atom_name (aSelectionData->type), aSelectionData->type); -// return; -// } -//} -// -/** - * No-op. - * - */ NS_IMETHODIMP nsClipboard::ForceDataToClipboard() { #ifdef DEBUG_CLIPBOARD @@ -401,83 +336,3 @@ NS_IMETHODIMP nsClipboard::ForceDataToClipboard() return NS_OK; } - -// -//// This is the callback which is called when another app -//// requests the selection. -//// -//void nsClipboard::SelectionGetCB(GtkWidget *widget, -// GtkSelectionData *aSelectionData, -// guint /*info*/, -// guint /*time*/, -// gpointer aData) -//{ -//#ifdef DEBUG_CLIPBOARD -// printf(" nsClipboard::SelectionGetCB\n"); -//#endif /* DEBUG_CLIPBOARD */ -// -// nsClipboard *clipboard = (nsClipboard *)aData; -// -// void *clipboardData; -// PRUint32 dataLength; -// nsresult rv; -// -// // Make sure we have a transferable: -// if (!clipboard->mTransferable) { -// printf("Clipboard has no transferable!\n"); -// return; -// } -// -// // XXX hack, string-only for now. -// // Create string data-flavor. -// nsString dataFlavor (kTextMime); -// -// // Get data out of transferable. -// rv = clipboard->mTransferable->GetTransferData(&dataFlavor, -// &clipboardData, -// &dataLength); -// -// // Currently we only offer the data in GDK_SELECTION_TYPE_STRING format. -// if (NS_SUCCEEDED(rv) && clipboardData && dataLength > 0) { -// gtk_selection_data_set(aSelectionData, -// GDK_SELECTION_TYPE_STRING, 8, -// (unsigned char *)clipboardData, -// dataLength); -// } -// else -// printf("Transferable didn't support the data flavor\n"); -//} -// -// -// -//// Called when another app requests selection ownership: -//void nsClipboard::SelectionClearCB(GtkWidget *widget, -// GdkEventSelection *event, -// gpointer data) -//{ -//#ifdef DEBUG_CLIPBOARD -// printf(" nsClipboard::SelectionClearCB\n"); -//#endif /* DEBUG_CLIPBOARD */ -//} -// -// -//// The routine called when another app asks for the content of the selection -//void -//nsClipboard::SelectionRequestCB (GtkWidget *aWidget, -// GtkSelectionData *aSelectionData, -// gpointer aData) -//{ -//#ifdef DEBUG_CLIPBOARD -// printf(" nsClipboard::SelectionRequestCB\n"); -//#endif /* DEBUG_CLIPBOARD */ -//} -// -//void -//nsClipboard::SelectionNotifyCB (GtkWidget *aWidget, -// GtkSelectionData *aSelectionData, -// gpointer aData) -//{ -//#ifdef DEBUG_CLIPBOARD -// printf(" nsClipboard::SelectionNotifyCB\n"); -//#endif /* DEBUG_CLIPBOARD */ -//} diff --git a/widget/src/beos/nsClipboard.h b/widget/src/beos/nsClipboard.h index 8aa46cc49b0..374e59f6eb2 100644 --- a/widget/src/beos/nsClipboard.h +++ b/widget/src/beos/nsClipboard.h @@ -17,7 +17,8 @@ * Copyright (C) 1998 Netscape Communications Corporation. All * Rights Reserved. * - * Contributor(s): + * Contributor(s): + * Takashi Toyoshima */ #ifndef nsClipboard_h__ @@ -27,8 +28,6 @@ #include class nsITransferable; -class nsIClipboardOwner; -class nsIWidget; /** * Native BeOS Clipboard wrapper @@ -41,9 +40,6 @@ public: nsClipboard(); virtual ~nsClipboard(); - //nsISupports - NS_DECL_ISUPPORTS_INHERITED - // nsIClipboard NS_IMETHOD ForceDataToClipboard(); @@ -57,36 +53,6 @@ protected: PRBool mIgnoreEmptyNotification; static BView *sView; - -// // Used for communicating pasted data -// // from the asynchronous X routines back to a blocking paste: -// GtkSelectionData mSelectionData; -// PRBool mBlocking; -// -// void SelectionReceiver(GtkWidget *aWidget, -// GtkSelectionData *aSelectionData); -// -// static void SelectionGetCB(GtkWidget *widget, -// GtkSelectionData *selection_data, -// guint /*info*/, -// guint /*time*/, -// gpointer data); -// -// static void SelectionClearCB(GtkWidget *widget, -// GdkEventSelection *event, -// gpointer data ); -// -// static void SelectionRequestCB(GtkWidget *aWidget, -// GtkSelectionData *aSelectionData, -// gpointer aData); -// -// static void SelectionReceivedCB(GtkWidget *aWidget, -// GtkSelectionData *aSelectionData, -// gpointer aData); -// -// static void SelectionNotifyCB(GtkWidget *aWidget, -// GtkSelectionData *aSelectionData, -// gpointer aData); }; #endif // nsClipboard_h__