summaryrefslogtreecommitdiff
path: root/firefox-2.0-dnd.patch
diff options
context:
space:
mode:
authorChristopher Aillon <caillon@fedoraproject.org>2007-08-04 19:37:08 +0000
committerChristopher Aillon <caillon@fedoraproject.org>2007-08-04 19:37:08 +0000
commitbe713dba96cda73cae41d3218ce2b069a5ced46c (patch)
tree636f7ad210a03e6e033dba591d78bc8cbfbc4799 /firefox-2.0-dnd.patch
parentadded config script (diff)
downloadlibrewolf-fedora-ff-be713dba96cda73cae41d3218ce2b069a5ced46c.tar.gz
librewolf-fedora-ff-be713dba96cda73cae41d3218ce2b069a5ced46c.tar.bz2
librewolf-fedora-ff-be713dba96cda73cae41d3218ce2b069a5ced46c.zip
- Update to 2.0.0.6
- Fix dnd support to/from gtk2 apps - Fix installed permissions of *.png
Diffstat (limited to 'firefox-2.0-dnd.patch')
-rw-r--r--firefox-2.0-dnd.patch949
1 files changed, 949 insertions, 0 deletions
diff --git a/firefox-2.0-dnd.patch b/firefox-2.0-dnd.patch
new file mode 100644
index 0000000..a26dcdb
--- /dev/null
+++ b/firefox-2.0-dnd.patch
@@ -0,0 +1,949 @@
+Index: widget/src/gtk2/nsClipboard.cpp
+===================================================================
+RCS file: /export/src/cvs/mozilla1.7/mozilla/widget/src/gtk2/nsClipboard.cpp,v
+retrieving revision 1.1.1.1
+diff -u -r1.1.1.1 nsClipboard.cpp
+--- widget/src/gtk2/nsClipboard.cpp 2004/04/13 06:46:17 1.1.1.1
++++ widget/src/gtk2/nsClipboard.cpp 2004/04/13 08:22:00
+@@ -73,7 +73,7 @@
+ GdkEventSelection *aEvent,
+ nsClipboard *aClipboard);
+
+-static void
++void
+ ConvertHTMLtoUCS2 (guchar *data,
+ PRInt32 dataLength,
+ PRUnichar **unicodeData,
+@@ -473,7 +473,6 @@
+ // utf-8.
+
+ PRInt32 whichClipboard;
+-
+ // which clipboard?
+ if (aSelectionData->selection == GDK_SELECTION_PRIMARY)
+ whichClipboard = kSelectionClipboard;
+@@ -547,16 +546,8 @@
+ * 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);
++ addBOM(NS_REINTERPRET_CAST(guchar **, &primitive_data),
++ NS_REINTERPRET_CAST(gint *, &len));
+ }
+
+ gtk_selection_data_set(aSelectionData, aSelectionData->target,
+@@ -736,6 +727,22 @@
+ return;
+ }
+ str.AssignLiteral("UNKNOWN");
++}
++
++void addBOM(guchar **data, gint *len)
++{
++ guchar* indata = *data;
++ gint inlen = *len;
++ guchar *buffer = (guchar *)
++ nsMemory::Alloc((inlen * sizeof(guchar)) + sizeof(PRUnichar));
++ if (!buffer)
++ return;
++ PRUnichar prefix = 0xFEFF;
++ memcpy(buffer, &prefix, sizeof(prefix));
++ memcpy(buffer + sizeof(prefix), indata, inlen);
++ nsMemory::Free((guchar *)indata);
++ *data = (guchar *)buffer;
++ *len += sizeof(prefix);
+ }
+
+ static void
+Index: widget/src/gtk2/nsClipboard.h
+===================================================================
+RCS file: /export/src/cvs/mozilla1.7/mozilla/widget/src/gtk2/nsClipboard.h,v
+retrieving revision 1.1.1.1
+diff -u -r1.1.1.1 nsClipboard.h
+--- widget/src/gtk2/nsClipboard.h 2004/04/13 06:46:17 1.1.1.1
++++ widget/src/gtk2/nsClipboard.h 2004/04/13 08:22:00
+@@ -87,4 +87,6 @@
+
+ };
+
++void addBOM(guchar **data, gint *len);
++
+ #endif /* __nsClipboard_h_ */
+Index: widget/src/gtk2/nsDragService.cpp
+===================================================================
+RCS file: /export/src/cvs/mozilla1.7/mozilla/widget/src/gtk2/nsDragService.cpp,v
+retrieving revision 1.1.1.1
+diff -u -r1.1.1.1 nsDragService.cpp
+--- widget/src/gtk2/nsDragService.cpp 2004/04/13 06:46:17 1.1.1.1
++++ widget/src/gtk2/nsDragService.cpp 2004/04/13 08:22:00
+@@ -41,6 +41,8 @@
+ #include <gtk/gtkinvisible.h>
+ #include <gdk/gdkx.h>
+ #include "nsCRT.h"
++#include "nsString.h"
++#include "nsReadableUtils.h"
+
+
+ static PRLogModuleInfo *sDragLm = NULL;
+@@ -49,6 +51,9 @@
+ static const char gMozUrlType[] = "_NETSCAPE_URL";
+ static const char gTextUriListType[] = "text/uri-list";
+
++static const char gPlainTextUTF16[] = "text/plain;charset=utf-16";
++static const char gPlainTextUTF8[] = "text/plain;charset=utf-8";
++
+ NS_IMPL_ADDREF_INHERITED(nsDragService, nsBaseDragService)
+ NS_IMPL_RELEASE_INHERITED(nsDragService, nsBaseDragService)
+ NS_IMPL_QUERY_INTERFACE4(nsDragService,
+@@ -57,6 +62,10 @@
+ nsIDragSessionGTK,
+ nsIObserver)
+
++void addBOM(guchar **data, gint *len);
++void ConvertHTMLtoUCS2(guchar * data, PRInt32 dataLength,
++ PRUnichar** unicodeData, PRInt32& outUnicodeLen);
++
+ static void
+ invisibleSourceDragEnd(GtkWidget *aWidget,
+ GdkDragContext *aContext,
+@@ -70,6 +79,38 @@
+ guint32 aTime,
+ gpointer aData);
+
++struct AutoConvertTargetPair {
++ const char * internal; // the drag data receiving side
++ const char * outside; // the drag data providing side
++ TargetConverter out2in;
++ TargetConverter in2out;
++};
++
++//converters
++static void utf8_to_ucs2 (const char *aDataIn, unsigned int aDataInLen,
++ char **aDataOut, unsigned int *aDataOutLen);
++static void ucs2_to_text (const char *aDataIn, unsigned int aDataInLen,
++ char **aDataOut, unsigned int *aDataOutLen);
++static void text_to_ucs2 (const char *aDataIn, unsigned int aDataInLen,
++ char **aDataOut, unsigned int *aDataOutLen);
++
++// The table used to match an internal target to an outside target
++// the entry comes early has high priority in matching
++static const AutoConvertTargetPair autoConvertPair[] = {
++ {kUnicodeMime, "UTF8_STRING", utf8_to_ucs2, ucs2_to_text},
++ {kUnicodeMime, "COMPOUND_TEXT", utf8_to_ucs2, ucs2_to_text},
++ {kUnicodeMime, "TEXT", utf8_to_ucs2, ucs2_to_text},
++ {kUnicodeMime, "STRING", utf8_to_ucs2, ucs2_to_text},
++ {kUnicodeMime, kTextMime, text_to_ucs2, ucs2_to_text},
++ {kUnicodeMime, gPlainTextUTF16, NULL, NULL},
++ {kUnicodeMime, gPlainTextUTF8, text_to_ucs2, ucs2_to_text},
++
++ {kURLMime, gTextUriListType, NULL, ucs2_to_text},
++ {kURLMime, gMozUrlType, text_to_ucs2, ucs2_to_text},
++
++ {NULL, NULL, NULL, NULL},
++};
++
+ nsDragService::nsDragService()
+ {
+ // We have to destroy the hidden widget before the event loop stops
+@@ -92,7 +133,7 @@
+
+ // set up our logging module
+ if (!sDragLm)
+- sDragLm = PR_NewLogModule("nsDragService");
++ sDragLm = PR_NewLogModule("nsDragService");
+ PR_LOG(sDragLm, PR_LOG_DEBUG, ("nsDragService::nsDragService"));
+ mTargetWidget = 0;
+ mTargetDragContext = 0;
+@@ -101,6 +142,8 @@
+ mTargetDragDataReceived = PR_FALSE;
+ mTargetDragData = 0;
+ mTargetDragDataLen = 0;
++ mTargetDragGdkAtom = 0;
++ mTargetConverter = NULL;
+ }
+
+ nsDragService::~nsDragService()
+@@ -173,6 +216,16 @@
+ event.button.window = mHiddenWidget->window;
+ event.button.time = nsWindow::mLastButtonPressTime;
+
++ event.button.send_event = 0;
++ event.button.x = 0;
++ event.button.y = 0;
++ event.button.state = 0;
++ event.button.button = 0;
++ event.button.device = 0;
++ event.button.x_root = 0;
++ event.button.y_root = 0;
++
++
+ // start our drag.
+ GdkDragContext *context = gtk_drag_begin(mHiddenWidget,
+ sourceList,
+@@ -291,7 +344,7 @@
+ NS_IMETHODIMP
+ nsDragService::GetNumDropItems(PRUint32 * aNumItems)
+ {
+- PR_LOG(sDragLm, PR_LOG_DEBUG, ("nsDragService::GetNumDropItems"));
++ PR_LOG(sDragLm, PR_LOG_DEBUG, ("==nsDragService::GetNumDropItems==\n"));
+ PRBool isList = IsTargetContextList();
+ if (isList)
+ mSourceDataItems->Count(aNumItems);
+@@ -303,8 +356,9 @@
+ *aNumItems = CountTextUriListItems(data, mTargetDragDataLen);
+ } else
+ *aNumItems = 1;
++ TargetResetData();
+ }
+- PR_LOG(sDragLm, PR_LOG_DEBUG, ("%d items", *aNumItems));
++ PR_LOG(sDragLm, PR_LOG_DEBUG, ("%d items\n", *aNumItems));
+ return NS_OK;
+ }
+
+@@ -360,7 +414,7 @@
+ PRUint32 tmpDataLen = 0;
+ PR_LOG(sDragLm, PR_LOG_DEBUG,
+ ("trying to get transfer data for %s\n",
+- (const char *)flavorStr));
++ (const char *)flavorStr));
+ rv = item->GetTransferData(flavorStr,
+ getter_AddRefs(data),
+ &tmpDataLen);
+@@ -387,6 +441,7 @@
+ // Now walk down the list of flavors. When we find one that is
+ // actually present, copy out the data into the transferable in that
+ // format. SetTransferData() implicitly handles conversions.
++
+ for ( i = 0; i < cnt; ++i ) {
+ nsCOMPtr<nsISupports> genericWrapper;
+ flavorList->GetElementAt(i,getter_AddRefs(genericWrapper));
+@@ -399,118 +454,58 @@
+ GdkAtom gdkFlavor = gdk_atom_intern(flavorStr, FALSE);
+ PR_LOG(sDragLm, PR_LOG_DEBUG,
+ ("looking for data in type %s, gdk flavor %ld\n",
+- NS_STATIC_CAST(const char*,flavorStr), gdkFlavor));
++ NS_STATIC_CAST(const char*,flavorStr), gdkFlavor));
+ PRBool dataFound = PR_FALSE;
+ if (gdkFlavor) {
+ GetTargetDragData(gdkFlavor);
+ }
+ if (mTargetDragData) {
+- PR_LOG(sDragLm, PR_LOG_DEBUG, ("dataFound = PR_TRUE\n"));
++ PR_LOG(sDragLm, PR_LOG_DEBUG,
++ ("dataFound = PR_TRUE for %s\n", gdk_atom_name(mTargetDragGdkAtom)));
+ dataFound = PR_TRUE;
+- }
+- else {
+- PR_LOG(sDragLm, PR_LOG_DEBUG, ("dataFound = PR_FALSE\n"));
+- // if we are looking for text/unicode and we fail to find it
+- // on the clipboard first, try again with text/plain. If that
+- // is present, convert it to unicode.
+- if ( strcmp(flavorStr, kUnicodeMime) == 0 ) {
+- PR_LOG(sDragLm, PR_LOG_DEBUG,
+- ("we were looking for text/unicode... \
+- trying again with text/plain\n"));
+- gdkFlavor = gdk_atom_intern(kTextMime, FALSE);
+- GetTargetDragData(gdkFlavor);
+- if (mTargetDragData) {
+- PR_LOG(sDragLm, PR_LOG_DEBUG, ("Got textplain data\n"));
+- const char* castedText =
+- NS_REINTERPRET_CAST(char*, mTargetDragData);
+- PRUnichar* convertedText = nsnull;
+- PRInt32 convertedTextLen = 0;
+- nsPrimitiveHelpers::ConvertPlatformPlainTextToUnicode(
+- castedText, mTargetDragDataLen,
+- &convertedText, &convertedTextLen);
+- if ( convertedText ) {
+- PR_LOG(sDragLm, PR_LOG_DEBUG,
+- ("successfully converted plain text \
+- to unicode.\n"));
+- // out with the old, in with the new
+- g_free(mTargetDragData);
+- mTargetDragData = convertedText;
+- mTargetDragDataLen = convertedTextLen * 2;
+- dataFound = PR_TRUE;
+- } // if plain text data on clipboard
+- } // if plain text flavor present
+- } // if looking for text/unicode
+-
+- // if we are looking for text/x-moz-url and we failed to find
+- // it on the clipboard, try again with text/uri-list, and then
+- // _NETSCAPE_URL
+- if (strcmp(flavorStr, kURLMime) == 0) {
++
++ // we need to do extra work for text/uri-list
++ if (mTargetDragGdkAtom ==
++ gdk_atom_intern(gTextUriListType, FALSE)) {
+ PR_LOG(sDragLm, PR_LOG_DEBUG,
+- ("we were looking for text/x-moz-url...\
+- trying again with text/uri-list\n"));
+- gdkFlavor = gdk_atom_intern(gTextUriListType, FALSE);
+- GetTargetDragData(gdkFlavor);
+- if (mTargetDragData) {
+- PR_LOG(sDragLm, PR_LOG_DEBUG,
+- ("Got text/uri-list data\n"));
+- const char *data =
+- NS_REINTERPRET_CAST(char*, mTargetDragData);
+- PRUnichar* convertedText = nsnull;
+- PRInt32 convertedTextLen = 0;
++ ("Converting text/uri-list data\n"));
++ const char *data =
++ NS_REINTERPRET_CAST(char*, mTargetDragData);
++ PRUnichar* convertedText = nsnull;
++ PRInt32 convertedTextLen = 0;
+
+- GetTextUriListItem(data, mTargetDragDataLen, aItemIndex,
+- &convertedText, &convertedTextLen);
++ GetTextUriListItem(data, mTargetDragDataLen, aItemIndex,
++ &convertedText, &convertedTextLen);
+
+- if ( convertedText ) {
+- PR_LOG(sDragLm, PR_LOG_DEBUG,
+- ("successfully converted \
+- _NETSCAPE_URL to unicode.\n"));
+- // out with the old, in with the new
+- g_free(mTargetDragData);
+- mTargetDragData = convertedText;
+- mTargetDragDataLen = convertedTextLen * 2;
+- dataFound = PR_TRUE;
+- }
+- }
+- else {
++ if (convertedText) {
+ PR_LOG(sDragLm, PR_LOG_DEBUG,
+- ("failed to get text/uri-list data\n"));
++ ("successfully converted \
++ %s to unicode.\n", gTextUriListType));
++ // out with the old, in with the new
++ g_free(mTargetDragData);
++ mTargetDragData = convertedText;
++ mTargetDragDataLen = convertedTextLen * 2;
+ }
+- if (!dataFound) {
+- PR_LOG(sDragLm, PR_LOG_DEBUG,
+- ("we were looking for text/x-moz-url...\
+- trying again with _NETSCAP_URL\n"));
+- gdkFlavor = gdk_atom_intern(gMozUrlType, FALSE);
+- GetTargetDragData(gdkFlavor);
+- if (mTargetDragData) {
+- PR_LOG(sDragLm, PR_LOG_DEBUG,
+- ("Got _NETSCAPE_URL data\n"));
+- const char* castedText =
+- NS_REINTERPRET_CAST(char*, mTargetDragData);
+- PRUnichar* convertedText = nsnull;
+- PRInt32 convertedTextLen = 0;
+- nsPrimitiveHelpers::ConvertPlatformPlainTextToUnicode(castedText, mTargetDragDataLen, &convertedText, &convertedTextLen);
+- if ( convertedText ) {
+- PR_LOG(sDragLm,
+- PR_LOG_DEBUG,
+- ("successfully converted _NETSCAPE_URL \
+- to unicode.\n"));
+- // out with the old, in with the new
+- g_free(mTargetDragData);
+- mTargetDragData = convertedText;
+- mTargetDragDataLen = convertedTextLen * 2;
+- dataFound = PR_TRUE;
+- }
+- }
+- else {
+- PR_LOG(sDragLm, PR_LOG_DEBUG,
+- ("failed to get _NETSCAPE_URL data\n"));
+- }
+- }
+ }
+-
+- } // else we try one last ditch effort to find our data
+-
++ // Convert text/html into our unicode format
++ else if (mTargetDragGdkAtom ==
++ gdk_atom_intern(kHTMLMime, FALSE)) {
++ PRUnichar* htmlBody= nsnull;
++ PRInt32 htmlBodyLen = 0;
++
++ ConvertHTMLtoUCS2(NS_STATIC_CAST(guchar*, mTargetDragData),
++ mTargetDragDataLen,
++ &htmlBody, htmlBodyLen);
++ if (!htmlBodyLen)
++ break;
++ g_free(mTargetDragData);
++ mTargetDragData = (void *)htmlBody;
++ mTargetDragDataLen = htmlBodyLen * 2;
++ }
++ }
++ else {
++ PR_LOG(sDragLm, PR_LOG_DEBUG, ("dataFound = PR_FALSE\n"));
++ }
+ if (dataFound) {
+ // the DOM only wants LF, so convert from MacOS line endings
+ // to DOM line endings.
+@@ -542,7 +537,7 @@
+ nsDragService::IsDataFlavorSupported(const char *aDataFlavor,
+ PRBool *_retval)
+ {
+- PR_LOG(sDragLm, PR_LOG_DEBUG, ("nsDragService::IsDataFlavorSupported %s",
++ PR_LOG(sDragLm, PR_LOG_DEBUG, ("nsDragService::IsDataFlavorSupported %s\n",
+ aDataFlavor));
+ if (!_retval)
+ return NS_ERROR_INVALID_ARG;
+@@ -595,7 +590,7 @@
+ currentFlavor->ToString(getter_Copies(flavorStr));
+ PR_LOG(sDragLm, PR_LOG_DEBUG,
+ ("checking %s against %s\n",
+- (const char *)flavorStr, aDataFlavor));
++ (const char *)flavorStr, aDataFlavor));
+ if (strcmp(flavorStr, aDataFlavor) == 0) {
+ PR_LOG(sDragLm, PR_LOG_DEBUG,
+ ("boioioioiooioioioing!\n"));
+@@ -609,50 +604,9 @@
+ return NS_OK;
+ }
+
+- // check the target context vs. this flavor, one at a time
+- GList *tmp;
+- for (tmp = mTargetDragContext->targets; tmp; tmp = tmp->next) {
+- GdkAtom atom = (GdkAtom)GPOINTER_TO_INT(tmp->data);
+- gchar *name = NULL;
+- name = gdk_atom_name(atom);
+- PR_LOG(sDragLm, PR_LOG_DEBUG,
+- ("checking %s against %s\n", name, aDataFlavor));
+- if (name && (strcmp(name, aDataFlavor) == 0)) {
+- PR_LOG(sDragLm, PR_LOG_DEBUG, ("good!\n"));
+- *_retval = PR_TRUE;
+- }
+- // check for automatic text/uri-list -> text/x-moz-url mapping
+- if (*_retval == PR_FALSE &&
+- name &&
+- (strcmp(name, gTextUriListType) == 0) &&
+- (strcmp(aDataFlavor, kURLMime) == 0)) {
+- PR_LOG(sDragLm, PR_LOG_DEBUG,
+- ("good! ( it's text/uri-list and \
+- we're checking against text/x-moz-url )\n"));
+- *_retval = PR_TRUE;
+- }
+- // check for automatic _NETSCAPE_URL -> text/x-moz-url mapping
+- if (*_retval == PR_FALSE &&
+- name &&
+- (strcmp(name, gMozUrlType) == 0) &&
+- (strcmp(aDataFlavor, kURLMime) == 0)) {
+- PR_LOG(sDragLm, PR_LOG_DEBUG,
+- ("good! ( it's _NETSCAPE_URL and \
+- we're checking against text/x-moz-url )\n"));
+- *_retval = PR_TRUE;
+- }
+- // check for auto text/plain -> text/unicode mapping
+- if (*_retval == PR_FALSE &&
+- name &&
+- (strcmp(name, kTextMime) == 0) &&
+- (strcmp(aDataFlavor, kUnicodeMime) == 0)) {
+- PR_LOG(sDragLm, PR_LOG_DEBUG,
+- ("good! ( it's text plain and we're checking \
+- against text/unicode )\n"));
+- *_retval = PR_TRUE;
+- }
+- g_free(name);
+- }
++ if (LookupFlavorInTargetList(aDataFlavor) ||
++ LookupMatchedOutsideTarget(aDataFlavor, NULL, NULL))
++ *_retval = PR_TRUE;
+ return NS_OK;
+ }
+
+@@ -691,14 +645,14 @@
+ // notify the dragger if we can drop
+ switch (mDragAction) {
+ case DRAGDROP_ACTION_COPY:
+- action = GDK_ACTION_COPY;
+- break;
++ action = GDK_ACTION_COPY;
++ break;
+ case DRAGDROP_ACTION_LINK:
+- action = GDK_ACTION_LINK;
+- break;
++ action = GDK_ACTION_LINK;
++ break;
+ default:
+- action = GDK_ACTION_MOVE;
+- break;
++ action = GDK_ACTION_MOVE;
++ break;
+ }
+ gdk_drag_status(aContext, action, aTime);
+ }
+@@ -719,12 +673,23 @@
+ guint32 aTime)
+ {
+ PR_LOG(sDragLm, PR_LOG_DEBUG, ("nsDragService::TargetDataReceived"));
+- TargetResetData();
++ NS_ASSERTION(mTargetDragData == 0, "Data area is NOT empty!!\n");
++ NS_ASSERTION(mTargetDragDataLen == 0, "Data area is NOT empty!!\n");
++
+ mTargetDragDataReceived = PR_TRUE;
+ if (aSelectionData->length > 0) {
+- mTargetDragDataLen = aSelectionData->length;
+- mTargetDragData = g_malloc(mTargetDragDataLen);
+- memcpy(mTargetDragData, aSelectionData->data, mTargetDragDataLen);
++ if (mTargetDragGdkAtom && mTargetConverter) {
++ // need Converting
++ (*mTargetConverter)((const char*)aSelectionData->data,
++ aSelectionData->length,
++ (char **)&mTargetDragData,
++ &mTargetDragDataLen);
++ }
++ else {
++ mTargetDragDataLen = aSelectionData->length;
++ mTargetDragData = g_malloc(mTargetDragDataLen);
++ memcpy(mTargetDragData, aSelectionData->data, mTargetDragDataLen);
++ }
+ }
+ else {
+ PR_LOG(sDragLm, PR_LOG_DEBUG,
+@@ -781,13 +746,31 @@
+ void
+ nsDragService::GetTargetDragData(GdkAtom aFlavor)
+ {
+- PR_LOG(sDragLm, PR_LOG_DEBUG, ("getting data flavor %d\n", aFlavor));
+- PR_LOG(sDragLm, PR_LOG_DEBUG, ("mLastWidget is %p and mLastContext is %p\n",
+- mTargetWidget, mTargetDragContext));
++ const char *flavorStr = gdk_atom_name(aFlavor);
++ PR_LOG(sDragLm, PR_LOG_DEBUG, ("GetTargetData with flavor %s\n", flavorStr));
++ PR_LOG(sDragLm, PR_LOG_DEBUG,
++ ("mLastWidget is %p, mLastContext is %p\n",
++ (void*)mTargetWidget, (void*)mTargetDragContext));
+ // reset our target data areas
+ TargetResetData();
+- gtk_drag_get_data(mTargetWidget, mTargetDragContext, aFlavor, mTargetTime);
+-
++ // if it is a direct match
++ if (LookupFlavorInTargetList(flavorStr)) {
++ gtk_drag_get_data(mTargetWidget, mTargetDragContext,
++ aFlavor, mTargetTime);
++ mTargetDragGdkAtom = aFlavor;
++
++ }
++ // if it is a auto converting match
++ else if (LookupMatchedOutsideTarget(flavorStr,
++ &mTargetDragGdkAtom,
++ &mTargetConverter))
++ gtk_drag_get_data(mTargetWidget, mTargetDragContext,
++ mTargetDragGdkAtom, mTargetTime);
++ else {
++ PR_LOG(sDragLm, PR_LOG_DEBUG, ("Cannot request target %s\n",
++ flavorStr));
++ return;
++ }
+ PR_LOG(sDragLm, PR_LOG_DEBUG, ("about to start inner iteration."));
+ PRTime entryTime = PR_Now();
+ while (!mTargetDragDataReceived && mDoingDrag) {
+@@ -807,9 +791,11 @@
+ mTargetDragDataReceived = PR_FALSE;
+ // make sure to free old data if we have to
+ if (mTargetDragData)
+- g_free(mTargetDragData);
++ g_free(mTargetDragData);
+ mTargetDragData = 0;
+ mTargetDragDataLen = 0;
++ mTargetDragGdkAtom = 0;
++ mTargetConverter = NULL;
+ }
+
+ GtkTargetList *
+@@ -841,7 +827,7 @@
+ listTarget->info = (guint)listAtom;
+ PR_LOG(sDragLm, PR_LOG_DEBUG,
+ ("automatically adding target %s with id %ld\n",
+- listTarget->target, listAtom));
++ listTarget->target, listAtom));
+ targetArray.AppendElement(listTarget);
+
+ // check what flavours are supported so we can decide what other
+@@ -861,7 +847,7 @@
+ ++flavorIndex ) {
+ nsCOMPtr<nsISupports> genericWrapper;
+ flavorList->GetElementAt(flavorIndex,
+- getter_AddRefs(genericWrapper));
++ getter_AddRefs(genericWrapper));
+ nsCOMPtr<nsISupportsCString> currentFlavor;
+ currentFlavor = do_QueryInterface(genericWrapper);
+ if (currentFlavor) {
+@@ -908,51 +894,27 @@
+ if (currentFlavor) {
+ nsXPIDLCString flavorStr;
+ currentFlavor->ToString(getter_Copies(flavorStr));
+- // get the atom
+- GdkAtom atom = gdk_atom_intern(flavorStr, FALSE);
+- GtkTargetEntry *target =
+- (GtkTargetEntry *)g_malloc(sizeof(GtkTargetEntry));
+- target->target = g_strdup(flavorStr);
+- target->flags = 0;
+- target->info = GPOINTER_TO_UINT(atom);
++ //add the target itself
++ GtkTargetEntry *target = CreateGtkTargetFor(flavorStr);
+ PR_LOG(sDragLm, PR_LOG_DEBUG,
+- ("adding target %s with id %ld\n",
+- target->target, atom));
++ ("+++adding importable target %s\n",
++ target->target));
+ targetArray.AppendElement(target);
+- // Check to see if this is text/unicode.
+- // If it is, add text/plain
+- // since we automatically support text/plain
+- // if we support text/unicode.
+- if (strcmp(flavorStr, kUnicodeMime) == 0) {
+- // get the atom for the unicode string
+- GdkAtom plainAtom =
+- gdk_atom_intern(kTextMime, FALSE);
+- GtkTargetEntry *plainTarget =
+- (GtkTargetEntry *)g_malloc(sizeof(GtkTargetEntry));
+- plainTarget->target = g_strdup(kTextMime);
+- plainTarget->flags = 0;
+- plainTarget->info = GPOINTER_TO_UINT(plainAtom);
+- PR_LOG(sDragLm, PR_LOG_DEBUG,
+- ("automatically adding target %s with \
+- id %ld\n", plainTarget->target, plainAtom));
+- targetArray.AppendElement(plainTarget);
+- }
+- // Check to see if this is the x-moz-url type.
+- // If it is, add _NETSCAPE_URL
+- // this is a type used by everybody.
+- if (strcmp(flavorStr, kURLMime) == 0) {
+- // get the atom name for it
+- GdkAtom urlAtom =
+- gdk_atom_intern(gMozUrlType, FALSE);
+- GtkTargetEntry *urlTarget =
+- (GtkTargetEntry *)g_malloc(sizeof(GtkTargetEntry));
+- urlTarget->target = g_strdup(gMozUrlType);
+- urlTarget->flags = 0;
+- urlTarget->info = GPOINTER_TO_UINT(urlAtom);
+- PR_LOG(sDragLm, PR_LOG_DEBUG,
+- ("automatically adding target %s with \
+- id %ld\n", urlTarget->target, urlAtom));
+- targetArray.AppendElement(urlTarget);
++
++ //add the auto convert targets
++ PRUint16 convIndex = 0;
++ while (autoConvertPair[convIndex].internal &&
++ autoConvertPair[convIndex].outside) {
++ if (!strcmp(autoConvertPair[convIndex].internal,
++ flavorStr)) {
++ target = CreateGtkTargetFor( \
++ autoConvertPair[convIndex].outside);
++ PR_LOG(sDragLm, PR_LOG_DEBUG,
++ (" ++auto adding target %s\n",
++ target->target));
++ targetArray.AppendElement(target);
++ }
++ ++convIndex;
+ }
+ }
+ } // foreach flavor in item
+@@ -965,11 +927,11 @@
+ if (targetCount) {
+ // allocate space to create the list of valid targets
+ targets =
+- (GtkTargetEntry *)g_malloc(sizeof(GtkTargetEntry) * targetCount);
++ (GtkTargetEntry *)g_malloc(sizeof(GtkTargetEntry) * targetCount);
+ PRUint32 targetIndex;
+ for ( targetIndex = 0; targetIndex < targetCount; ++targetIndex) {
+ GtkTargetEntry *disEntry =
+- (GtkTargetEntry *)targetArray.ElementAt(targetIndex);
++ (GtkTargetEntry *)targetArray.ElementAt(targetIndex);
+ // this is a string reference but it will be freed later.
+ targets[targetIndex].target = disEntry->target;
+ targets[targetIndex].flags = disEntry->flags;
+@@ -979,7 +941,7 @@
+ // clean up the target list
+ for (PRUint32 cleanIndex = 0; cleanIndex < targetCount; ++cleanIndex) {
+ GtkTargetEntry *thisTarget =
+- (GtkTargetEntry *)targetArray.ElementAt(cleanIndex);
++ (GtkTargetEntry *)targetArray.ElementAt(cleanIndex);
+ g_free(thisTarget->target);
+ g_free(thisTarget);
+ }
+@@ -1067,7 +1029,7 @@
+ guint aInfo,
+ guint32 aTime)
+ {
+- PR_LOG(sDragLm, PR_LOG_DEBUG, ("nsDragService::SourceDataGet"));
++ PR_LOG(sDragLm, PR_LOG_DEBUG, ("\nnsDragService::SourceDataGet"));
+ GdkAtom atom = (GdkAtom)aInfo;
+ nsXPIDLCString mimeFlavor;
+ gchar *typeName = 0;
+@@ -1104,22 +1066,18 @@
+ nsCOMPtr<nsITransferable> item;
+ item = do_QueryInterface(genericItem);
+ if (item) {
+- // if someone was asking for text/plain, lookup unicode instead so
+- // we can convert it.
+- PRBool needToDoConversionToPlainText = PR_FALSE;
++ TargetConverter converter = NULL;
+ const char* actualFlavor = mimeFlavor;
+- if (strcmp(mimeFlavor,kTextMime) == 0) {
+- actualFlavor = kUnicodeMime;
+- needToDoConversionToPlainText = PR_TRUE;
+- }
+- // if someone was asking for _NETSCAPE_URL we need to convert to
+- // plain text but we also need to look for x-moz-url
+- else if (strcmp(mimeFlavor, gMozUrlType) == 0) {
+- actualFlavor = kURLMime;
+- needToDoConversionToPlainText = PR_TRUE;
++ PRUint32 convIndex = 0;
++ while (autoConvertPair[convIndex].outside &&
++ autoConvertPair[convIndex].internal) {
++ if (!strcmp(mimeFlavor, autoConvertPair[convIndex].outside)) {
++ actualFlavor = autoConvertPair[convIndex].internal;
++ converter = autoConvertPair[convIndex].in2out;
++ break;
++ }
++ ++convIndex;
+ }
+- else
+- actualFlavor = mimeFlavor;
+
+ PRUint32 tmpDataLen = 0;
+ void *tmpData = NULL;
+@@ -1131,18 +1089,24 @@
+ if (NS_SUCCEEDED(rv)) {
+ nsPrimitiveHelpers::CreateDataFromPrimitive (actualFlavor, data,
+ &tmpData, tmpDataLen);
++
++ if (strcmp(actualFlavor, kHTMLMime) == 0) {
++ PR_LOG(sDragLm, PR_LOG_DEBUG, ("add BOM prefix for %s\n",
++ kHTMLMime));
++ addBOM(NS_REINTERPRET_CAST(guchar **, &tmpData),
++ NS_REINTERPRET_CAST(gint *, &tmpDataLen));
++ }
++
+ // if required, do the extra work to convert unicode to plain
+ // text and replace the output values with the plain text.
+- if (needToDoConversionToPlainText) {
++ if (converter) {
+ char* plainTextData = nsnull;
+ PRUnichar* castedUnicode = NS_REINTERPRET_CAST(PRUnichar*,
+ tmpData);
+- PRInt32 plainTextLen = 0;
+- nsPrimitiveHelpers::ConvertUnicodeToPlatformPlainText(
+- castedUnicode,
+- tmpDataLen / 2,
+- &plainTextData,
+- &plainTextLen);
++ PRUint32 plainTextLen = 0;
++ (*converter)((const char*)castedUnicode, tmpDataLen,
++ &plainTextData, &plainTextLen);
++
+ if (tmpData) {
+ // this was not allocated using glib
+ free(tmpData);
+@@ -1190,3 +1154,149 @@
+ dragService->SourceEndDrag();
+ }
+
++PRBool
++nsDragService::LookupFlavorInTargetList(const char *aDataFlavor)
++{
++ PR_LOG(sDragLm, PR_LOG_DEBUG,
++ ("nsDragService::LookupFlavorInTargetList,"
++ "checking %s \n", aDataFlavor));
++
++ if (!mTargetDragContext || !aDataFlavor)
++ return PR_FALSE;
++
++ GList *targetList = mTargetDragContext->targets;
++ while (targetList) {
++ GdkAtom atom = (GdkAtom)GPOINTER_TO_INT(targetList->data);
++ gchar *atomName = gdk_atom_name(atom);
++ PR_LOG(sDragLm, PR_LOG_DEBUG,
++ ("checking %s against %s\n", aDataFlavor, atomName));
++ if (atomName && (strcmp(atomName, aDataFlavor) == 0)) {
++ PR_LOG(sDragLm, PR_LOG_DEBUG, ("good!\n"));
++ g_free(atomName);
++ return PR_TRUE;
++ }
++ targetList = targetList->next;
++ }
++ return PR_FALSE;
++}
++
++PRBool
++nsDragService::LookupMatchedOutsideTarget(const char *aDataFlavor,
++ GdkAtom *aAtom,
++ TargetConverter *aConverter)
++{
++ PR_LOG(sDragLm, PR_LOG_DEBUG,
++ ("nsDragService::LookupMatchedOutsideTarget,"
++ "checking %s \n", aDataFlavor));
++
++ if (!mTargetDragContext || !aDataFlavor)
++ return PR_FALSE;
++
++ gint index = 0;
++ while (autoConvertPair[index].internal &&
++ autoConvertPair[index].outside) {
++ if (!strcmp(autoConvertPair[index].internal, aDataFlavor) &&
++ LookupFlavorInTargetList(autoConvertPair[index].outside)) {
++ if (aConverter)
++ *aConverter = autoConvertPair[index].out2in;
++ if (aAtom)
++ *aAtom = gdk_atom_intern(autoConvertPair[index].outside,
++ FALSE);
++ return PR_TRUE;
++ }
++ ++index;
++ }
++ return PR_FALSE;
++}
++
++PRBool
++nsDragService::LookupMatchedInternalTarget(const char *aDataFlavor,
++ GdkAtom *aAtom,
++ TargetConverter *aConverter)
++{
++ PR_LOG(sDragLm, PR_LOG_DEBUG,
++ ("nsDragService::LookupMatchedInternalTarget,"
++ "checking %s \n", aDataFlavor));
++
++ if (!mTargetDragContext || !aDataFlavor)
++ return PR_FALSE;
++
++ gint index = 0;
++ while (autoConvertPair[index].internal &&
++ autoConvertPair[index].outside) {
++ if (!strcmp(autoConvertPair[index].outside, aDataFlavor) &&
++ LookupFlavorInTargetList(autoConvertPair[index].internal)) {
++ if (aConverter)
++ *aConverter = autoConvertPair[index].in2out;
++ if (aAtom)
++ *aAtom = gdk_atom_intern(autoConvertPair[index].internal,
++ FALSE);
++ return PR_TRUE;
++ }
++ ++index;
++ }
++ return PR_FALSE;
++}
++
++GtkTargetEntry *
++nsDragService::CreateGtkTargetFor(const char *aFlavorStr)
++{
++ // get the atom
++ GdkAtom atom = gdk_atom_intern(aFlavorStr, FALSE);
++ GtkTargetEntry *target =
++ (GtkTargetEntry *)g_malloc(sizeof(GtkTargetEntry));
++ NS_ASSERTION(target, "No enough mem");
++
++ target->target = g_strdup(aFlavorStr);
++ target->flags = 0;
++ target->info = (guint)atom;
++
++ return target;
++}
++
++//converters
++
++// static
++void
++utf8_to_ucs2 (const char *aDataIn, unsigned int aDataInLen,
++ char **aDataOut, unsigned int *aDataOutLen)
++{
++ nsAutoString ucs2string = NS_ConvertUTF8toUCS2(aDataIn);
++ *aDataOut = (char *)ToNewUnicode(ucs2string);
++ *aDataOutLen = ucs2string.Length() * 2;
++
++ PR_LOG(sDragLm, PR_LOG_DEBUG,
++ ("AutoConverting: utf8 ---> unicode.\n"));
++
++}
++
++//static
++void
++ucs2_to_text (const char *aDataIn, unsigned int aDataInLen,
++ char **aDataOut, unsigned int *aDataOutLen)
++{
++ nsPrimitiveHelpers::
++ ConvertUnicodeToPlatformPlainText((PRUnichar *)aDataIn,
++ int(aDataInLen / 2),
++ aDataOut, (PRInt32 *)aDataOutLen);
++ PR_LOG(sDragLm, PR_LOG_DEBUG,
++ ("AutoConverting: ucs2 ---> platform text.\n"));
++}
++
++//static
++void
++text_to_ucs2 (const char *aDataIn, unsigned int aDataInLen,
++ char **aDataOut, unsigned int *aDataOutLen)
++{
++ PRUnichar *convertedText = nsnull;
++ PRInt32 convertedTextLen = 0;
++ nsPrimitiveHelpers::
++ ConvertPlatformPlainTextToUnicode(aDataIn, aDataInLen,
++ &convertedText, &convertedTextLen);
++ if (convertedText) {
++ PR_LOG(sDragLm, PR_LOG_DEBUG,
++ ("AutoConverting: plain text ---> unicode.\n"));
++ *aDataOut = NS_REINTERPRET_CAST(char*, convertedText);
++ *aDataOutLen = convertedTextLen * 2;
++ }
++}
+Index: widget/src/gtk2/nsDragService.h
+===================================================================
+RCS file: /export/src/cvs/mozilla1.7/mozilla/widget/src/gtk2/nsDragService.h,v
+retrieving revision 1.1.1.1
+diff -u -r1.1.1.1 nsDragService.h
+--- widget/src/gtk2/nsDragService.h 2004/04/13 06:46:17 1.1.1.1
++++ widget/src/gtk2/nsDragService.h 2004/04/13 08:22:00
+@@ -33,6 +33,8 @@
+ #include "nsIObserver.h"
+ #include <gtk/gtk.h>
+
++typedef void (*TargetConverter) (const char *aDataIn, unsigned int aDataInLen,
++ char **aDataOut, unsigned int *aDataOutLen);
+
+ /**
+ * Native GTK DragService wrapper
+@@ -64,7 +66,8 @@
+ NS_IMETHOD GetNumDropItems (PRUint32 * aNumItems);
+ NS_IMETHOD GetData (nsITransferable * aTransferable,
+ PRUint32 aItemIndex);
+- NS_IMETHOD IsDataFlavorSupported (const char *aDataFlavor, PRBool *_retval);
++ NS_IMETHOD IsDataFlavorSupported (const char *aDataFlavor,
++ PRBool *_retval);
+
+ // nsIDragSessionGTK
+
+@@ -112,6 +115,9 @@
+ // last data received and its length
+ void *mTargetDragData;
+ PRUint32 mTargetDragDataLen;
++ GdkAtom mTargetDragGdkAtom; // the real target we asked for
++ TargetConverter mTargetConverter; //
++
+ // is the current target drag context contain a list?
+ PRBool IsTargetContextList(void);
+ // this will get the native data from the last target given a
+@@ -129,7 +135,17 @@
+ // get a list of the sources in gtk's format
+ GtkTargetList *GetSourceList(void);
+
++ // check if a flavor supported by source target list
++ PRBool LookupFlavorInTargetList(const char *aDataFlavor);
++ PRBool LookupMatchedOutsideTarget(const char *aDataFlavor,
++ GdkAtom *aAtom,
++ TargetConverter *aConverter);
++ PRBool LookupMatchedInternalTarget(const char *aDataFlavor,
++ GdkAtom *aAtom,
++ TargetConverter *aConverter);
++
++ GtkTargetEntry *CreateGtkTargetFor(const char *aFlavorStr);
++
+ };
+
+ #endif // nsDragService_h__
+-
bgstack15