diff -Naur mozilla-1.9.1/widget/src/gtk2/nsClipboard.cpp mozilla-1.9.1-patched/widget/src/gtk2/nsClipboard.cpp --- mozilla-1.9.1/widget/src/gtk2/nsClipboard.cpp 2009-06-17 06:22:21.000000000 +0200 +++ mozilla-1.9.1-patched/widget/src/gtk2/nsClipboard.cpp 2009-06-22 12:28:39.566251241 +0200 @@ -63,19 +63,6 @@ #include #endif -// Callback when someone asks us for the selection -void -invisible_selection_get_cb (GtkWidget *aWidget, - GtkSelectionData *aSelectionData, - guint aTime, - guint aInfo, - nsClipboard *aClipboard); - -gboolean -selection_clear_event_cb (GtkWidget *aWidget, - GdkEventSelection *aEvent, - nsClipboard *aClipboard); - static void ConvertHTMLtoUCS2 (guchar *data, PRInt32 dataLength, @@ -141,14 +128,6 @@ if (!mWidget) return NS_ERROR_FAILURE; - g_signal_connect(G_OBJECT(mWidget), "selection_get", - G_CALLBACK(invisible_selection_get_cb), this); - - g_signal_connect(G_OBJECT(mWidget), "selection_clear_event", - G_CALLBACK(selection_clear_event_cb), this); - - // XXX make sure to set up the selection_clear event - return NS_OK; } @@ -156,16 +135,6 @@ nsClipboard::SetData(nsITransferable *aTransferable, nsIClipboardOwner *aOwner, PRInt32 aWhichClipboard) { - // See if we can short cut - if ((aWhichClipboard == kGlobalClipboard && - aTransferable == mGlobalTransferable.get() && - aOwner == mGlobalOwner.get()) || - (aWhichClipboard == kSelectionClipboard && - aTransferable == mSelectionTransferable.get() && - aOwner == mSelectionOwner.get())) { - return NS_OK; - } - nsresult rv; if (!mPrivacyHandler) { rv = NS_NewClipboardPrivacyHandler(getter_AddRefs(mPrivacyHandler)); @@ -174,28 +143,6 @@ rv = mPrivacyHandler->PrepareDataForClipboard(aTransferable); NS_ENSURE_SUCCESS(rv, rv); - // Clear out the clipboard in order to set the new data - EmptyClipboard(aWhichClipboard); - - if (aWhichClipboard == kSelectionClipboard) { - mSelectionOwner = aOwner; - mSelectionTransferable = aTransferable; - } - else { - mGlobalOwner = aOwner; - mGlobalTransferable = aTransferable; - } - - // Which selection are we about to claim, CLIPBOARD or PRIMARY? - GdkAtom selectionAtom = GetSelectionAtom(aWhichClipboard); - - // Make ourselves the owner. If we fail to, return. - if (!gtk_selection_owner_set(mWidget, selectionAtom, GDK_CURRENT_TIME)) - return NS_ERROR_FAILURE; - - // Clear the old selection target list. - gtk_selection_clear_targets(mWidget, selectionAtom); - // Get the types of supported flavors nsCOMPtr flavors; @@ -203,6 +150,9 @@ if (!flavors || NS_FAILED(rv)) return NS_ERROR_FAILURE; + + GtkClipboard *aClipboard = gtk_clipboard_get(GetSelectionAtom(aWhichClipboard)); + // Add all the flavors to this widget's supported type. PRUint32 count; flavors->Count(&count); @@ -215,32 +165,19 @@ nsXPIDLCString flavorStr; flavor->ToString(getter_Copies(flavorStr)); - // special case text/unicode since we can handle all of - // the string types - if (!strcmp(flavorStr, kUnicodeMime)) { - AddTarget(gdk_atom_intern("UTF8_STRING", FALSE), - selectionAtom); - AddTarget(gdk_atom_intern("COMPOUND_TEXT", FALSE), - selectionAtom); - AddTarget(gdk_atom_intern("TEXT", FALSE), selectionAtom); - AddTarget(GDK_SELECTION_TYPE_STRING, selectionAtom); - // next loop iteration - continue; - } + nsCOMPtr item; + PRUint32 len; + rv = aTransferable->GetTransferData(flavorStr, getter_AddRefs(item), &len); - // very special case for this one. since our selection mechanism doesn't work for images, - // we must use GTK's clipboard utility functions + //Handle images if (!strcmp(flavorStr, kNativeImageMime) || !strcmp(flavorStr, kPNGImageMime) || !strcmp(flavorStr, kJPEGImageMime) || !strcmp(flavorStr, kGIFImageMime)) { - nsCOMPtr item; - PRUint32 len; - rv = aTransferable->GetTransferData(flavorStr, getter_AddRefs(item), &len); nsCOMPtr ptrPrimitive(do_QueryInterface(item)); if (!ptrPrimitive) continue; - nsCOMPtr primitiveData; ptrPrimitive->GetData(getter_AddRefs(primitiveData)); + nsCOMPtr image(do_QueryInterface(primitiveData)); if (!image) // Not getting an image for an image mime type!? continue; @@ -252,20 +189,33 @@ image->UnlockImagePixels(PR_FALSE); continue; } - - GtkClipboard *aClipboard = gtk_clipboard_get(GetSelectionAtom(aWhichClipboard)); + gtk_clipboard_set_image(aClipboard, pixbuf); g_object_unref(pixbuf); image->UnlockImagePixels(PR_FALSE); + continue; } - // Add this to our list of valid targets - GdkAtom atom = gdk_atom_intern(flavorStr, FALSE); - AddTarget(atom, selectionAtom); + //Handle text + if (!strcmp(flavorStr, kUnicodeMime)) { + void* data = nsnull; + + nsPrimitiveHelpers::CreateDataFromPrimitive(flavorStr, item, &data, len); + const PRUnichar* casted = (const PRUnichar*) data; + NS_ConvertUTF16toUTF8 conv(casted, (PRUint32)len / 2); + delete casted; + + gtk_clipboard_set_text(aClipboard, (const gchar*)conv.get(), -1); + + continue; + } } } + if (aWhichClipboard == kGlobalClipboard) + gtk_clipboard_store(aClipboard); + return NS_OK; } @@ -391,27 +341,6 @@ } NS_IMETHODIMP -nsClipboard::EmptyClipboard(PRInt32 aWhichClipboard) -{ - if (aWhichClipboard == kSelectionClipboard) { - if (mSelectionOwner) { - mSelectionOwner->LosingOwnership(mSelectionTransferable); - mSelectionOwner = nsnull; - } - mSelectionTransferable = nsnull; - } - else { - if (mGlobalOwner) { - mGlobalOwner->LosingOwnership(mGlobalTransferable); - mGlobalOwner = nsnull; - } - mGlobalTransferable = nsnull; - } - - return NS_OK; -} - -NS_IMETHODIMP nsClipboard::HasDataMatchingFlavors(const char** aFlavorList, PRUint32 aLength, PRInt32 aWhichClipboard, PRBool *_retval) { @@ -489,167 +418,22 @@ return wait_for_contents(clipboard, gdk_atom_intern("TARGETS", FALSE)); } -nsITransferable * -nsClipboard::GetTransferable(PRInt32 aWhichClipboard) -{ - nsITransferable *retval; - if (aWhichClipboard == kSelectionClipboard) - retval = mSelectionTransferable.get(); - else - retval = mGlobalTransferable.get(); - - return retval; -} - -void -nsClipboard::AddTarget(GdkAtom aName, GdkAtom aClipboard) -{ - gtk_selection_add_target(mWidget, aClipboard, aName, 0); -} - -void -nsClipboard::SelectionGetEvent (GtkWidget *aWidget, - GtkSelectionData *aSelectionData, - guint aTime) +NS_IMETHODIMP +nsClipboard::EmptyClipboard(PRInt32 aWhichClipboard) { - // Someone has asked us to hand them something. The first thing - // that we want to do is see if that something includes text. If - // it does, try to give it text/unicode after converting it to - // utf-8. - - PRInt32 whichClipboard; - - // which clipboard? - if (aSelectionData->selection == GDK_SELECTION_PRIMARY) - whichClipboard = kSelectionClipboard; - else if (aSelectionData->selection == GDK_SELECTION_CLIPBOARD) - whichClipboard = kGlobalClipboard; - else - return; // THAT AIN'T NO CLIPBOARD I EVER HEARD OF - - nsCOMPtr trans = GetTransferable(whichClipboard); - - nsresult rv; - nsCOMPtr item; - PRUint32 len; - - // Check to see if the selection data includes any of the string - // types that we support. - if (aSelectionData->target == gdk_atom_intern ("STRING", FALSE) || - aSelectionData->target == gdk_atom_intern ("TEXT", FALSE) || - aSelectionData->target == gdk_atom_intern ("COMPOUND_TEXT", FALSE) || - aSelectionData->target == gdk_atom_intern ("UTF8_STRING", FALSE)) { - // Try to convert our internal type into a text string. Get - // the transferable for this clipboard and try to get the - // text/unicode type for it. - rv = trans->GetTransferData("text/unicode", getter_AddRefs(item), - &len); - if (!item || NS_FAILED(rv)) - return; - - nsCOMPtr wideString; - wideString = do_QueryInterface(item); - if (!wideString) - return; - - nsAutoString ucs2string; - wideString->GetData(ucs2string); - char *utf8string = ToNewUTF8String(ucs2string); - if (!utf8string) - return; - - gtk_selection_data_set_text (aSelectionData, utf8string, - strlen(utf8string)); - - nsMemory::Free(utf8string); - return; - } - - // Try to match up the selection data target to something our - // transferable provides. - gchar *target_name = gdk_atom_name(aSelectionData->target); - if (!target_name) - return; - - rv = trans->GetTransferData(target_name, getter_AddRefs(item), &len); - // nothing found? - if (!item || NS_FAILED(rv)) { - g_free(target_name); - return; - } - - void *primitive_data = nsnull; - nsPrimitiveHelpers::CreateDataFromPrimitive(target_name, item, - &primitive_data, len); - - if (primitive_data) { - // Check to see if the selection data is text/html - if (aSelectionData->target == gdk_atom_intern (kHTMLMime, FALSE)) { - /* - * "text/html" can be encoded UCS2. It is recommended that - * documents transmitted as UCS2 always begin with a ZERO-WIDTH - * NON-BREAKING SPACE character (hexadecimal FEFF, also called - * Byte Order Mark (BOM)). Adding BOM can help other app to - * detect mozilla use UCS2 encoding when copy-paste. - */ - guchar *buffer = (guchar *) - nsMemory::Alloc((len * sizeof(guchar)) + sizeof(PRUnichar)); - if (!buffer) - return; - PRUnichar prefix = 0xFEFF; - memcpy(buffer, &prefix, sizeof(prefix)); - memcpy(buffer + sizeof(prefix), primitive_data, len); - nsMemory::Free((guchar *)primitive_data); - primitive_data = (guchar *)buffer; - len += sizeof(prefix); - } - - gtk_selection_data_set(aSelectionData, aSelectionData->target, - 8, /* 8 bits in a unit */ - (const guchar *)primitive_data, len); - nsMemory::Free(primitive_data); + if (aWhichClipboard == kSelectionClipboard) + { + gtk_clipboard_clear ( gtk_clipboard_get(GetSelectionAtom(kSelectionClipboard))); } - - g_free(target_name); - -} - -void -nsClipboard::SelectionClearEvent (GtkWidget *aWidget, - GdkEventSelection *aEvent) -{ - PRInt32 whichClipboard; - - // which clipboard? - if (aEvent->selection == GDK_SELECTION_PRIMARY) - whichClipboard = kSelectionClipboard; - else if (aEvent->selection == GDK_SELECTION_CLIPBOARD) - whichClipboard = kGlobalClipboard; else - return; // THAT AIN'T NO CLIPBOARD I EVER HEARD OF - - EmptyClipboard(whichClipboard); -} + { + gtk_clipboard_clear ( gtk_clipboard_get(GetSelectionAtom(kGlobalClipboard))); + } -void -invisible_selection_get_cb (GtkWidget *aWidget, - GtkSelectionData *aSelectionData, - guint aTime, - guint aInfo, - nsClipboard *aClipboard) -{ - aClipboard->SelectionGetEvent(aWidget, aSelectionData, aTime); + return NS_OK; } -gboolean -selection_clear_event_cb (GtkWidget *aWidget, - GdkEventSelection *aEvent, - nsClipboard *aClipboard) -{ - aClipboard->SelectionClearEvent(aWidget, aEvent); - return TRUE; -} /* * when copy-paste, mozilla wants data encoded using UCS2, diff -Naur mozilla-1.9.1/widget/src/gtk2/nsClipboard.h mozilla-1.9.1-patched/widget/src/gtk2/nsClipboard.h --- mozilla-1.9.1/widget/src/gtk2/nsClipboard.h 2009-06-17 06:22:21.000000000 +0200 +++ mozilla-1.9.1-patched/widget/src/gtk2/nsClipboard.h 2009-06-22 12:28:43.751250557 +0200 @@ -57,37 +57,15 @@ // Make sure we are initialized, called from the factory // constructor nsresult Init (void); - // Someone requested the selection from the hidden widget - void SelectionGetEvent (GtkWidget *aWidget, - GtkSelectionData *aSelectionData, - guint aTime); - void SelectionClearEvent (GtkWidget *aWidget, - GdkEventSelection *aEvent); - - private: // Utility methods static GdkAtom GetSelectionAtom (PRInt32 aWhichClipboard); static GtkSelectionData *GetTargets (GdkAtom aWhichClipboard); - // Get our hands on the correct transferable, given a specific - // clipboard - nsITransferable *GetTransferable (PRInt32 aWhichClipboard); - - // Add a target type to the hidden widget - void AddTarget (GdkAtom aName, - GdkAtom aClipboard); - // The hidden widget where we do all of our operations GtkWidget *mWidget; - // Hang on to our owners and transferables so we can transfer data - // when asked. - nsCOMPtr mSelectionOwner; - nsCOMPtr mGlobalOwner; - nsCOMPtr mSelectionTransferable; - nsCOMPtr mGlobalTransferable; - nsRefPtr mPrivacyHandler; + nsRefPtr mPrivacyHandler; }; #endif /* __nsClipboard_h_ */