mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1243507 - Reimplement non-Unicode clipboard formats as bug 943294 broke drag and drop between some Unicode-unaware apps. r=jimm
This commit is contained in:
parent
d2142aaa0b
commit
2b932ae233
@ -92,8 +92,9 @@ UINT nsClipboard::GetFormat(const char* aMimeStr)
|
||||
{
|
||||
UINT format;
|
||||
|
||||
if (strcmp(aMimeStr, kTextMime) == 0 ||
|
||||
strcmp(aMimeStr, kUnicodeMime) == 0)
|
||||
if (strcmp(aMimeStr, kTextMime) == 0)
|
||||
format = CF_TEXT;
|
||||
else if (strcmp(aMimeStr, kUnicodeMime) == 0)
|
||||
format = CF_UNICODETEXT;
|
||||
else if (strcmp(aMimeStr, kRTFMime) == 0)
|
||||
format = ::RegisterClipboardFormat(L"Rich Text Format");
|
||||
@ -179,7 +180,14 @@ nsresult nsClipboard::SetupNativeDataObject(nsITransferable * aTransferable, IDa
|
||||
// Do various things internal to the implementation, like map one
|
||||
// flavor to another or add additional flavors based on what's required
|
||||
// for the win32 impl.
|
||||
if ( strcmp(flavorStr, kHTMLMime) == 0 ) {
|
||||
if ( strcmp(flavorStr, kUnicodeMime) == 0 ) {
|
||||
// if we find text/unicode, also advertise text/plain (which we will convert
|
||||
// on our own in nsDataObj::GetText().
|
||||
FORMATETC textFE;
|
||||
SET_FORMATETC(textFE, CF_TEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL);
|
||||
dObj->AddDataFlavor(kTextMime, &textFE);
|
||||
}
|
||||
else if ( strcmp(flavorStr, kHTMLMime) == 0 ) {
|
||||
// if we find text/html, also advertise win32's html flavor (which we will convert
|
||||
// on our own in nsDataObj::GetText().
|
||||
FORMATETC htmlFE;
|
||||
@ -191,10 +199,14 @@ nsresult nsClipboard::SetupNativeDataObject(nsITransferable * aTransferable, IDa
|
||||
// the "file" flavors so that the win32 shell knows to create an internet
|
||||
// shortcut when it sees one of these beasts.
|
||||
FORMATETC shortcutFE;
|
||||
SET_FORMATETC(shortcutFE, ::RegisterClipboardFormat(CFSTR_FILEDESCRIPTORA), 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL)
|
||||
dObj->AddDataFlavor(kURLMime, &shortcutFE);
|
||||
SET_FORMATETC(shortcutFE, ::RegisterClipboardFormat(CFSTR_FILEDESCRIPTORW), 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL)
|
||||
dObj->AddDataFlavor(kURLMime, &shortcutFE);
|
||||
SET_FORMATETC(shortcutFE, ::RegisterClipboardFormat(CFSTR_FILECONTENTS), 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL)
|
||||
dObj->AddDataFlavor(kURLMime, &shortcutFE);
|
||||
SET_FORMATETC(shortcutFE, ::RegisterClipboardFormat(CFSTR_INETURLA), 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL)
|
||||
dObj->AddDataFlavor(kURLMime, &shortcutFE);
|
||||
SET_FORMATETC(shortcutFE, ::RegisterClipboardFormat(CFSTR_INETURLW), 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL)
|
||||
dObj->AddDataFlavor(kURLMime, &shortcutFE);
|
||||
}
|
||||
@ -607,9 +619,11 @@ nsresult nsClipboard::GetDataFromDataObject(IDataObject * aDataObject,
|
||||
// when directly asking for the flavor. Let's try digging around in other
|
||||
// flavors to help satisfy our craving for data.
|
||||
if ( !dataFound ) {
|
||||
if ( strcmp(flavorStr, kURLMime) == 0 ) {
|
||||
if ( strcmp(flavorStr, kUnicodeMime) == 0 )
|
||||
dataFound = FindUnicodeFromPlainText ( aDataObject, anIndex, &data, &dataLen );
|
||||
else if ( strcmp(flavorStr, kURLMime) == 0 ) {
|
||||
// drags from other windows apps expose the native
|
||||
// CFSTR_INETURLW flavor
|
||||
// CFSTR_INETURL{A,W} flavor
|
||||
dataFound = FindURLFromNativeURL ( aDataObject, anIndex, &data, &dataLen );
|
||||
if ( !dataFound )
|
||||
dataFound = FindURLFromLocalFile ( aDataObject, anIndex, &data, &dataLen );
|
||||
@ -759,6 +773,39 @@ nsClipboard :: FindPlatformHTML ( IDataObject* inDataObject, UINT inIndex,
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// FindUnicodeFromPlainText
|
||||
//
|
||||
// we are looking for text/unicode and we failed to find it on the clipboard first,
|
||||
// try again with text/plain. If that is present, convert it to unicode.
|
||||
//
|
||||
bool
|
||||
nsClipboard :: FindUnicodeFromPlainText ( IDataObject* inDataObject, UINT inIndex, void** outData, uint32_t* outDataLen )
|
||||
{
|
||||
// we are looking for text/unicode and we failed to find it on the clipboard first,
|
||||
// try again with text/plain. If that is present, convert it to unicode.
|
||||
nsresult rv = GetNativeDataOffClipboard(inDataObject, inIndex, GetFormat(kTextMime), nullptr, outData, outDataLen);
|
||||
if (NS_FAILED(rv) || !*outData) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const char* castedText = static_cast<char*>(*outData);
|
||||
nsAutoString tmp;
|
||||
rv = NS_CopyNativeToUnicode(nsDependentCSubstring(castedText, *outDataLen), tmp);
|
||||
if (NS_FAILED(rv)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// out with the old, in with the new
|
||||
free(*outData);
|
||||
*outData = ToNewUnicode(tmp);
|
||||
*outDataLen = tmp.Length() * sizeof(char16_t);
|
||||
|
||||
return true;
|
||||
|
||||
} // FindUnicodeFromPlainText
|
||||
|
||||
|
||||
//
|
||||
// FindURLFromLocalFile
|
||||
//
|
||||
@ -825,7 +872,7 @@ nsClipboard :: FindURLFromLocalFile ( IDataObject* inDataObject, UINT inIndex, v
|
||||
//
|
||||
// we are looking for a URL and couldn't find it using our internal
|
||||
// URL flavor, so look for it using the native URL flavor,
|
||||
// CF_INETURLSTRW
|
||||
// CF_INETURLSTRW (We don't handle CF_INETURLSTRA currently)
|
||||
//
|
||||
bool
|
||||
nsClipboard :: FindURLFromNativeURL ( IDataObject* inDataObject, UINT inIndex, void** outData, uint32_t* outDataLen )
|
||||
@ -846,6 +893,29 @@ nsClipboard :: FindURLFromNativeURL ( IDataObject* inDataObject, UINT inIndex, v
|
||||
free(tempOutData);
|
||||
dataFound = true;
|
||||
}
|
||||
else {
|
||||
loadResult = GetNativeDataOffClipboard(inDataObject, inIndex, ::RegisterClipboardFormat(CFSTR_INETURLA), nullptr, &tempOutData, &tempDataLen);
|
||||
if ( NS_SUCCEEDED(loadResult) && tempOutData ) {
|
||||
// CFSTR_INETURLA is (currently) equal to CFSTR_SHELLURL which is equal to CF_TEXT
|
||||
// which is by definition ANSI encoded.
|
||||
nsCString urlUnescapedA;
|
||||
bool unescaped = NS_UnescapeURL(static_cast<char*>(tempOutData), tempDataLen, esc_OnlyNonASCII | esc_SkipControl, urlUnescapedA);
|
||||
|
||||
nsString urlString;
|
||||
if (unescaped)
|
||||
NS_CopyNativeToUnicode(urlUnescapedA, urlString);
|
||||
else
|
||||
NS_CopyNativeToUnicode(nsDependentCString(static_cast<char*>(tempOutData), tempDataLen), urlString);
|
||||
|
||||
// the internal mozilla URL format, text/x-moz-url, contains
|
||||
// URL\ntitle. Since we don't actually have a title here,
|
||||
// just repeat the URL to fake it.
|
||||
*outData = ToNewUnicode(urlString + NS_LITERAL_STRING("\n") + urlString);
|
||||
*outDataLen = NS_strlen(static_cast<char16_t*>(*outData)) * sizeof(char16_t);
|
||||
free(tempOutData);
|
||||
dataFound = true;
|
||||
}
|
||||
}
|
||||
|
||||
return dataFound;
|
||||
} // FindURLFromNativeURL
|
||||
@ -942,6 +1012,16 @@ NS_IMETHODIMP nsClipboard::HasDataMatchingFlavors(const char** aFlavorList,
|
||||
*_retval = true;
|
||||
break;
|
||||
}
|
||||
else {
|
||||
// We haven't found the exact flavor the client asked for, but maybe we can
|
||||
// still find it from something else that's on the clipboard...
|
||||
if (strcmp(aFlavorList[i], kUnicodeMime) == 0) {
|
||||
// client asked for unicode and it wasn't present, check if we have CF_TEXT.
|
||||
// We'll handle the actual data substitution in the data object.
|
||||
if (IsClipboardFormatAvailable(GetFormat(kTextMime)))
|
||||
*_retval = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -1290,7 +1290,27 @@ HRESULT nsDataObj::GetText(const nsACString & aDataFlavor, FORMATETC& aFE, STGME
|
||||
// by the appropriate size to account for the null (one char for CF_TEXT, one char16_t for
|
||||
// CF_UNICODETEXT).
|
||||
DWORD allocLen = (DWORD)len;
|
||||
if ( aFE.cfFormat == nsClipboard::CF_HTML ) {
|
||||
if ( aFE.cfFormat == CF_TEXT ) {
|
||||
// Someone is asking for text/plain; convert the unicode (assuming it's present)
|
||||
// to text with the correct platform encoding.
|
||||
size_t bufferSize = sizeof(char)*(len + 2);
|
||||
char* plainTextData = static_cast<char*>(moz_xmalloc(bufferSize));
|
||||
char16_t* castedUnicode = reinterpret_cast<char16_t*>(data);
|
||||
int32_t plainTextLen = WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)castedUnicode, len / 2 + 1, plainTextData, bufferSize, NULL, NULL);
|
||||
// replace the unicode data with our plaintext data. Recall that |plainTextLen| doesn't include
|
||||
// the null in the length.
|
||||
free(data);
|
||||
if ( plainTextLen ) {
|
||||
data = plainTextData;
|
||||
allocLen = plainTextLen;
|
||||
}
|
||||
else {
|
||||
free(plainTextData);
|
||||
NS_WARNING ( "Oh no, couldn't convert unicode to plain text" );
|
||||
return S_OK;
|
||||
}
|
||||
}
|
||||
else if ( aFE.cfFormat == nsClipboard::CF_HTML ) {
|
||||
// Someone is asking for win32's HTML flavor. Convert our html fragment
|
||||
// from unicode to UTF-8 then put it into a format specified by msft.
|
||||
NS_ConvertUTF16toUTF8 converter ( reinterpret_cast<char16_t*>(data) );
|
||||
|
Loading…
Reference in New Issue
Block a user