michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: #define MOZILLA_INTERNAL_API michael@0: michael@0: #include michael@0: #include michael@0: michael@0: #include "TestHarness.h" michael@0: #include "nsIArray.h" michael@0: #include "nsIFile.h" michael@0: #include "nsNetUtil.h" michael@0: #include "nsISupportsPrimitives.h" michael@0: #include "nsIFileURL.h" michael@0: #include "nsITransferable.h" michael@0: #include "nsClipboard.h" michael@0: #include "nsDataObjCollection.h" michael@0: michael@0: nsIFile* xferFile; michael@0: michael@0: nsresult CheckValidHDROP(STGMEDIUM* pSTG) michael@0: { michael@0: if (pSTG->tymed != TYMED_HGLOBAL) { michael@0: fail("Received data is not in an HGLOBAL"); michael@0: return NS_ERROR_UNEXPECTED; michael@0: } michael@0: michael@0: HGLOBAL hGlobal = pSTG->hGlobal; michael@0: DROPFILES* pDropFiles; michael@0: pDropFiles = (DROPFILES*)GlobalLock(hGlobal); michael@0: if (!pDropFiles) { michael@0: fail("There is no data at the given HGLOBAL"); michael@0: return NS_ERROR_UNEXPECTED; michael@0: } michael@0: michael@0: if (pDropFiles->pFiles != sizeof(DROPFILES)) michael@0: fail("DROPFILES struct has wrong size"); michael@0: michael@0: if (pDropFiles->fWide != true) { michael@0: fail("Received data is not Unicode"); michael@0: return NS_ERROR_UNEXPECTED; michael@0: } michael@0: nsString s; michael@0: unsigned long offset = 0; michael@0: while (1) { michael@0: s = (char16_t*)((char*)pDropFiles + pDropFiles->pFiles + offset); michael@0: if (s.IsEmpty()) michael@0: break; michael@0: nsresult rv; michael@0: nsCOMPtr localFile( michael@0: do_CreateInstance(NS_LOCAL_FILE_CONTRACTID, &rv)); michael@0: rv = localFile->InitWithPath(s); michael@0: if (NS_FAILED(rv)) { michael@0: fail("File could not be opened"); michael@0: return NS_ERROR_UNEXPECTED; michael@0: } michael@0: offset += sizeof(char16_t) * (s.Length() + 1); michael@0: } michael@0: return NS_OK; michael@0: } michael@0: michael@0: nsresult CheckValidTEXT(STGMEDIUM* pSTG) michael@0: { michael@0: if (pSTG->tymed != TYMED_HGLOBAL) { michael@0: fail("Received data is not in an HGLOBAL"); michael@0: return NS_ERROR_UNEXPECTED; michael@0: } michael@0: michael@0: HGLOBAL hGlobal = pSTG->hGlobal; michael@0: char* pText; michael@0: pText = (char*)GlobalLock(hGlobal); michael@0: if (!pText) { michael@0: fail("There is no data at the given HGLOBAL"); michael@0: return NS_ERROR_UNEXPECTED; michael@0: } michael@0: michael@0: nsCString string; michael@0: string = pText; michael@0: michael@0: if (!string.Equals(NS_LITERAL_CSTRING("Mozilla can drag and drop"))) { michael@0: fail("Text passed through drop object wrong"); michael@0: return NS_ERROR_UNEXPECTED; michael@0: } michael@0: return NS_OK; michael@0: } michael@0: michael@0: nsresult CheckValidTEXTTwo(STGMEDIUM* pSTG) michael@0: { michael@0: if (pSTG->tymed != TYMED_HGLOBAL) { michael@0: fail("Received data is not in an HGLOBAL"); michael@0: return NS_ERROR_UNEXPECTED; michael@0: } michael@0: michael@0: HGLOBAL hGlobal = pSTG->hGlobal; michael@0: char* pText; michael@0: pText = (char*)GlobalLock(hGlobal); michael@0: if (!pText) { michael@0: fail("There is no data at the given HGLOBAL"); michael@0: return NS_ERROR_UNEXPECTED; michael@0: } michael@0: michael@0: nsCString string; michael@0: string = pText; michael@0: michael@0: if (!string.Equals(NS_LITERAL_CSTRING("Mozilla can drag and drop twice over"))) { michael@0: fail("Text passed through drop object wrong"); michael@0: return NS_ERROR_UNEXPECTED; michael@0: } michael@0: return NS_OK; michael@0: } michael@0: michael@0: nsresult CheckValidUNICODE(STGMEDIUM* pSTG) michael@0: { michael@0: if (pSTG->tymed != TYMED_HGLOBAL) { michael@0: fail("Received data is not in an HGLOBAL"); michael@0: return NS_ERROR_UNEXPECTED; michael@0: } michael@0: michael@0: HGLOBAL hGlobal = pSTG->hGlobal; michael@0: char16_t* pText; michael@0: pText = (char16_t*)GlobalLock(hGlobal); michael@0: if (!pText) { michael@0: fail("There is no data at the given HGLOBAL"); michael@0: return NS_ERROR_UNEXPECTED; michael@0: } michael@0: michael@0: nsString string; michael@0: string = pText; michael@0: michael@0: if (!string.Equals(NS_LITERAL_STRING("Mozilla can drag and drop"))) { michael@0: fail("Text passed through drop object wrong"); michael@0: return NS_ERROR_UNEXPECTED; michael@0: } michael@0: return NS_OK; michael@0: } michael@0: michael@0: nsresult CheckValidUNICODETwo(STGMEDIUM* pSTG) michael@0: { michael@0: if (pSTG->tymed != TYMED_HGLOBAL) { michael@0: fail("Received data is not in an HGLOBAL"); michael@0: return NS_ERROR_UNEXPECTED; michael@0: } michael@0: michael@0: HGLOBAL hGlobal = pSTG->hGlobal; michael@0: char16_t* pText; michael@0: pText = (char16_t*)GlobalLock(hGlobal); michael@0: if (!pText) { michael@0: fail("There is no data at the given HGLOBAL"); michael@0: return NS_ERROR_UNEXPECTED; michael@0: } michael@0: michael@0: nsString string; michael@0: string = pText; michael@0: michael@0: if (!string.Equals(NS_LITERAL_STRING("Mozilla can drag and drop twice over"))) { michael@0: fail("Text passed through drop object wrong"); michael@0: return NS_ERROR_UNEXPECTED; michael@0: } michael@0: return NS_OK; michael@0: } michael@0: michael@0: nsresult GetTransferableFile(nsCOMPtr& pTransferable) michael@0: { michael@0: nsresult rv; michael@0: michael@0: nsCOMPtr genericWrapper = do_QueryInterface(xferFile); michael@0: michael@0: pTransferable = do_CreateInstance("@mozilla.org/widget/transferable;1"); michael@0: pTransferable->Init(nullptr); michael@0: rv = pTransferable->SetTransferData("application/x-moz-file", genericWrapper, michael@0: 0); michael@0: return rv; michael@0: } michael@0: michael@0: nsresult GetTransferableText(nsCOMPtr& pTransferable) michael@0: { michael@0: nsresult rv; michael@0: NS_NAMED_LITERAL_STRING(mozString, "Mozilla can drag and drop"); michael@0: nsCOMPtr xferString = michael@0: do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID); michael@0: rv = xferString->SetData(mozString); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: nsCOMPtr genericWrapper = do_QueryInterface(xferString); michael@0: michael@0: pTransferable = do_CreateInstance("@mozilla.org/widget/transferable;1"); michael@0: pTransferable->Init(nullptr); michael@0: rv = pTransferable->SetTransferData("text/unicode", genericWrapper, michael@0: mozString.Length() * sizeof(char16_t)); michael@0: return rv; michael@0: } michael@0: michael@0: nsresult GetTransferableTextTwo(nsCOMPtr& pTransferable) michael@0: { michael@0: nsresult rv; michael@0: NS_NAMED_LITERAL_STRING(mozString, " twice over"); michael@0: nsCOMPtr xferString = michael@0: do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID); michael@0: rv = xferString->SetData(mozString); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: nsCOMPtr genericWrapper = do_QueryInterface(xferString); michael@0: michael@0: pTransferable = do_CreateInstance("@mozilla.org/widget/transferable;1"); michael@0: pTransferable->Init(nullptr); michael@0: rv = pTransferable->SetTransferData("text/unicode", genericWrapper, michael@0: mozString.Length() * sizeof(char16_t)); michael@0: return rv; michael@0: } michael@0: michael@0: nsresult GetTransferableURI(nsCOMPtr& pTransferable) michael@0: { michael@0: nsresult rv; michael@0: michael@0: nsCOMPtr xferURI; michael@0: michael@0: rv = NS_NewURI(getter_AddRefs(xferURI), "http://www.mozilla.org"); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: nsCOMPtr genericWrapper = do_QueryInterface(xferURI); michael@0: michael@0: pTransferable = do_CreateInstance("@mozilla.org/widget/transferable;1"); michael@0: pTransferable->Init(nullptr); michael@0: rv = pTransferable->SetTransferData("text/x-moz-url", genericWrapper, 0); michael@0: return rv; michael@0: } michael@0: michael@0: nsresult MakeDataObject(nsISupportsArray* transferableArray, michael@0: nsRefPtr& itemToDrag) michael@0: { michael@0: nsresult rv; michael@0: uint32_t itemCount = 0; michael@0: michael@0: nsCOMPtr uri; michael@0: rv = NS_NewURI(getter_AddRefs(uri), "http://www.mozilla.org"); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: rv = transferableArray->Count(&itemCount); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: // Copied more or less exactly from nsDragService::InvokeDragSession michael@0: // This is what lets us play fake Drag Service for the test michael@0: if (itemCount > 1) { michael@0: nsDataObjCollection * dataObjCollection = new nsDataObjCollection(); michael@0: if (!dataObjCollection) michael@0: return NS_ERROR_OUT_OF_MEMORY; michael@0: itemToDrag = dataObjCollection; michael@0: for (uint32_t i=0; i supports; michael@0: transferableArray->GetElementAt(i, getter_AddRefs(supports)); michael@0: nsCOMPtr trans(do_QueryInterface(supports)); michael@0: if (trans) { michael@0: nsRefPtr dataObj; michael@0: rv = nsClipboard::CreateNativeDataObject(trans, michael@0: getter_AddRefs(dataObj), uri); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: // Add the flavors to the collection object too michael@0: rv = nsClipboard::SetupNativeDataObject(trans, dataObjCollection); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: dataObjCollection->AddDataObject(dataObj); michael@0: } michael@0: } michael@0: } // if dragging multiple items michael@0: else { michael@0: nsCOMPtr supports; michael@0: transferableArray->GetElementAt(0, getter_AddRefs(supports)); michael@0: nsCOMPtr trans(do_QueryInterface(supports)); michael@0: if (trans) { michael@0: rv = nsClipboard::CreateNativeDataObject(trans, michael@0: getter_AddRefs(itemToDrag), michael@0: uri); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: } michael@0: } // else dragging a single object michael@0: return rv; michael@0: } michael@0: michael@0: nsresult Do_CheckOneFile() michael@0: { michael@0: nsresult rv; michael@0: nsCOMPtr transferable; michael@0: nsCOMPtr transferableArray; michael@0: nsCOMPtr genericWrapper; michael@0: nsRefPtr dataObj; michael@0: rv = NS_NewISupportsArray(getter_AddRefs(transferableArray)); michael@0: if (NS_FAILED(rv)) { michael@0: fail("Could not create the necessary nsISupportsArray"); michael@0: return rv; michael@0: } michael@0: michael@0: rv = GetTransferableFile(transferable); michael@0: if (NS_FAILED(rv)) { michael@0: fail("Could not create the proper nsITransferable!"); michael@0: return rv; michael@0: } michael@0: genericWrapper = do_QueryInterface(transferable); michael@0: rv = transferableArray->AppendElement(genericWrapper); michael@0: if (NS_FAILED(rv)) { michael@0: fail("Could not append element to transferable array"); michael@0: return rv; michael@0: } michael@0: michael@0: rv = MakeDataObject(transferableArray, dataObj); michael@0: if (NS_FAILED(rv)) { michael@0: fail("Could not create data object"); michael@0: return rv; michael@0: } michael@0: michael@0: FORMATETC fe; michael@0: SET_FORMATETC(fe, CF_HDROP, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL); michael@0: if (dataObj->QueryGetData(&fe) != S_OK) { michael@0: fail("File data object does not support the file data type!"); michael@0: return NS_ERROR_UNEXPECTED; michael@0: } michael@0: michael@0: STGMEDIUM* stg; michael@0: stg = (STGMEDIUM*)CoTaskMemAlloc(sizeof(STGMEDIUM)); michael@0: if (dataObj->GetData(&fe, stg) != S_OK) { michael@0: fail("File data object did not provide data on request"); michael@0: return NS_ERROR_UNEXPECTED; michael@0: } michael@0: michael@0: rv = CheckValidHDROP(stg); michael@0: if (NS_FAILED(rv)) { michael@0: fail("HDROP was invalid"); michael@0: return rv; michael@0: } michael@0: michael@0: ReleaseStgMedium(stg); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: nsresult Do_CheckTwoFiles() michael@0: { michael@0: nsresult rv; michael@0: nsCOMPtr transferable; michael@0: nsCOMPtr transferableArray; michael@0: nsCOMPtr genericWrapper; michael@0: nsRefPtr dataObj; michael@0: rv = NS_NewISupportsArray(getter_AddRefs(transferableArray)); michael@0: if (NS_FAILED(rv)) { michael@0: fail("Could not create the necessary nsISupportsArray"); michael@0: return rv; michael@0: } michael@0: michael@0: rv = GetTransferableFile(transferable); michael@0: if (NS_FAILED(rv)) { michael@0: fail("Could not create the proper nsITransferable!"); michael@0: return rv; michael@0: } michael@0: genericWrapper = do_QueryInterface(transferable); michael@0: rv = transferableArray->AppendElement(genericWrapper); michael@0: if (NS_FAILED(rv)) { michael@0: fail("Could not append element to transferable array"); michael@0: return rv; michael@0: } michael@0: michael@0: rv = GetTransferableFile(transferable); michael@0: if (NS_FAILED(rv)) { michael@0: fail("Could not create the proper nsITransferable!"); michael@0: return rv; michael@0: } michael@0: genericWrapper = do_QueryInterface(transferable); michael@0: rv = transferableArray->AppendElement(genericWrapper); michael@0: if (NS_FAILED(rv)) { michael@0: fail("Could not append element to transferable array"); michael@0: return rv; michael@0: } michael@0: michael@0: rv = MakeDataObject(transferableArray, dataObj); michael@0: if (NS_FAILED(rv)) { michael@0: fail("Could not create data object"); michael@0: return rv; michael@0: } michael@0: michael@0: FORMATETC fe; michael@0: SET_FORMATETC(fe, CF_HDROP, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL); michael@0: if (dataObj->QueryGetData(&fe) != S_OK) { michael@0: fail("File data object does not support the file data type!"); michael@0: return NS_ERROR_UNEXPECTED; michael@0: } michael@0: michael@0: STGMEDIUM* stg; michael@0: stg = (STGMEDIUM*)CoTaskMemAlloc(sizeof(STGMEDIUM)); michael@0: if (dataObj->GetData(&fe, stg) != S_OK) { michael@0: fail("File data object did not provide data on request"); michael@0: return NS_ERROR_UNEXPECTED; michael@0: } michael@0: michael@0: rv = CheckValidHDROP(stg); michael@0: if (NS_FAILED(rv)) { michael@0: fail("HDROP was invalid"); michael@0: return rv; michael@0: } michael@0: michael@0: ReleaseStgMedium(stg); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: nsresult Do_CheckOneString() michael@0: { michael@0: nsresult rv; michael@0: nsCOMPtr transferable; michael@0: nsCOMPtr transferableArray; michael@0: nsCOMPtr genericWrapper; michael@0: nsRefPtr dataObj; michael@0: rv = NS_NewISupportsArray(getter_AddRefs(transferableArray)); michael@0: if (NS_FAILED(rv)) { michael@0: fail("Could not create the necessary nsISupportsArray"); michael@0: return rv; michael@0: } michael@0: michael@0: rv = GetTransferableText(transferable); michael@0: if (NS_FAILED(rv)) { michael@0: fail("Could not create the proper nsITransferable!"); michael@0: return rv; michael@0: } michael@0: genericWrapper = do_QueryInterface(transferable); michael@0: rv = transferableArray->AppendElement(genericWrapper); michael@0: if (NS_FAILED(rv)) { michael@0: fail("Could not append element to transferable array"); michael@0: return rv; michael@0: } michael@0: michael@0: rv = MakeDataObject(transferableArray, dataObj); michael@0: if (NS_FAILED(rv)) { michael@0: fail("Could not create data object"); michael@0: return rv; michael@0: } michael@0: michael@0: FORMATETC fe; michael@0: SET_FORMATETC(fe, CF_TEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL); michael@0: if (dataObj->QueryGetData(&fe) != S_OK) { michael@0: fail("String data object does not support the ASCII text data type!"); michael@0: return NS_ERROR_UNEXPECTED; michael@0: } michael@0: michael@0: STGMEDIUM* stg; michael@0: stg = (STGMEDIUM*)CoTaskMemAlloc(sizeof(STGMEDIUM)); michael@0: if (dataObj->GetData(&fe, stg) != S_OK) { michael@0: fail("String data object did not provide ASCII data on request"); michael@0: return NS_ERROR_UNEXPECTED; michael@0: } michael@0: michael@0: rv = CheckValidTEXT(stg); michael@0: if (NS_FAILED(rv)) { michael@0: fail("TEXT was invalid"); michael@0: return rv; michael@0: } michael@0: michael@0: ReleaseStgMedium(stg); michael@0: michael@0: SET_FORMATETC(fe, CF_UNICODETEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL); michael@0: if (dataObj->QueryGetData(&fe) != S_OK) { michael@0: fail("String data object does not support the wide text data type!"); michael@0: return NS_ERROR_UNEXPECTED; michael@0: } michael@0: michael@0: if (dataObj->GetData(&fe, stg) != S_OK) { michael@0: fail("String data object did not provide wide data on request"); michael@0: return NS_ERROR_UNEXPECTED; michael@0: } michael@0: michael@0: rv = CheckValidUNICODE(stg); michael@0: if (NS_FAILED(rv)) { michael@0: fail("UNICODE was invalid"); michael@0: return rv; michael@0: } michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: nsresult Do_CheckTwoStrings() michael@0: { michael@0: nsresult rv; michael@0: nsCOMPtr transferable; michael@0: nsCOMPtr transferableArray; michael@0: nsCOMPtr genericWrapper; michael@0: nsRefPtr dataObj; michael@0: rv = NS_NewISupportsArray(getter_AddRefs(transferableArray)); michael@0: if (NS_FAILED(rv)) { michael@0: fail("Could not create the necessary nsISupportsArray"); michael@0: return rv; michael@0: } michael@0: michael@0: rv = GetTransferableText(transferable); michael@0: if (NS_FAILED(rv)) { michael@0: fail("Could not create the proper nsITransferable!"); michael@0: return rv; michael@0: } michael@0: genericWrapper = do_QueryInterface(transferable); michael@0: rv = transferableArray->AppendElement(genericWrapper); michael@0: if (NS_FAILED(rv)) { michael@0: fail("Could not append element to transferable array"); michael@0: return rv; michael@0: } michael@0: michael@0: rv = GetTransferableTextTwo(transferable); michael@0: if (NS_FAILED(rv)) { michael@0: fail("Could not create the proper nsITransferable!"); michael@0: return rv; michael@0: } michael@0: genericWrapper = do_QueryInterface(transferable); michael@0: rv = transferableArray->AppendElement(genericWrapper); michael@0: if (NS_FAILED(rv)) { michael@0: fail("Could not append element to transferable array"); michael@0: return rv; michael@0: } michael@0: michael@0: rv = MakeDataObject(transferableArray, dataObj); michael@0: if (NS_FAILED(rv)) { michael@0: fail("Could not create data object"); michael@0: return rv; michael@0: } michael@0: michael@0: FORMATETC fe; michael@0: SET_FORMATETC(fe, CF_TEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL); michael@0: if (dataObj->QueryGetData(&fe) != S_OK) { michael@0: fail("String data object does not support the ASCII text data type!"); michael@0: return NS_ERROR_UNEXPECTED; michael@0: } michael@0: michael@0: STGMEDIUM* stg; michael@0: stg = (STGMEDIUM*)CoTaskMemAlloc(sizeof(STGMEDIUM)); michael@0: if (dataObj->GetData(&fe, stg) != S_OK) { michael@0: fail("String data object did not provide ASCII data on request"); michael@0: return NS_ERROR_UNEXPECTED; michael@0: } michael@0: michael@0: rv = CheckValidTEXTTwo(stg); michael@0: if (NS_FAILED(rv)) { michael@0: fail("TEXT was invalid"); michael@0: return rv; michael@0: } michael@0: michael@0: ReleaseStgMedium(stg); michael@0: michael@0: SET_FORMATETC(fe, CF_UNICODETEXT, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL); michael@0: if (dataObj->QueryGetData(&fe) != S_OK) { michael@0: fail("String data object does not support the wide text data type!"); michael@0: return NS_ERROR_UNEXPECTED; michael@0: } michael@0: michael@0: if (dataObj->GetData(&fe, stg) != S_OK) { michael@0: fail("String data object did not provide wide data on request"); michael@0: return NS_ERROR_UNEXPECTED; michael@0: } michael@0: michael@0: rv = CheckValidUNICODETwo(stg); michael@0: if (NS_FAILED(rv)) { michael@0: fail("UNICODE was invalid"); michael@0: return rv; michael@0: } michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: nsresult Do_CheckSetArbitraryData(bool aMultiple) michael@0: { michael@0: nsresult rv; michael@0: nsCOMPtr transferable; michael@0: nsCOMPtr transferableArray; michael@0: nsCOMPtr genericWrapper; michael@0: nsRefPtr dataObj; michael@0: rv = NS_NewISupportsArray(getter_AddRefs(transferableArray)); michael@0: if (NS_FAILED(rv)) { michael@0: fail("Could not create the necessary nsISupportsArray"); michael@0: return rv; michael@0: } michael@0: michael@0: rv = GetTransferableText(transferable); michael@0: if (NS_FAILED(rv)) { michael@0: fail("Could not create the proper nsITransferable!"); michael@0: return rv; michael@0: } michael@0: genericWrapper = do_QueryInterface(transferable); michael@0: rv = transferableArray->AppendElement(genericWrapper); michael@0: if (NS_FAILED(rv)) { michael@0: fail("Could not append element to transferable array"); michael@0: return rv; michael@0: } michael@0: michael@0: if (aMultiple) { michael@0: rv = GetTransferableText(transferable); michael@0: if (NS_FAILED(rv)) { michael@0: fail("Could not create the proper nsITransferable!"); michael@0: return rv; michael@0: } michael@0: genericWrapper = do_QueryInterface(transferable); michael@0: rv = transferableArray->AppendElement(genericWrapper); michael@0: if (NS_FAILED(rv)) { michael@0: fail("Could not append element to transferable array"); michael@0: return rv; michael@0: } michael@0: } michael@0: michael@0: rv = MakeDataObject(transferableArray, dataObj); michael@0: if (NS_FAILED(rv)) { michael@0: fail("Could not create data object"); michael@0: return rv; michael@0: } michael@0: michael@0: static CLIPFORMAT mozArbitraryFormat = michael@0: ::RegisterClipboardFormatW(L"MozillaTestFormat"); michael@0: FORMATETC fe; michael@0: STGMEDIUM stg; michael@0: SET_FORMATETC(fe, mozArbitraryFormat, 0, DVASPECT_CONTENT, -1, TYMED_HGLOBAL); michael@0: michael@0: HGLOBAL hg = GlobalAlloc(GPTR, 1024); michael@0: stg.tymed = TYMED_HGLOBAL; michael@0: stg.hGlobal = hg; michael@0: stg.pUnkForRelease = nullptr; michael@0: michael@0: if (dataObj->SetData(&fe, &stg, true) != S_OK) { michael@0: if (aMultiple) { michael@0: fail("Unable to set arbitrary data type on data object collection!"); michael@0: } else { michael@0: fail("Unable to set arbitrary data type on data object!"); michael@0: } michael@0: return NS_ERROR_UNEXPECTED; michael@0: } michael@0: michael@0: if (dataObj->QueryGetData(&fe) != S_OK) { michael@0: fail("Arbitrary data set on data object is not advertised!"); michael@0: return NS_ERROR_UNEXPECTED; michael@0: } michael@0: michael@0: STGMEDIUM* stg2; michael@0: stg2 = (STGMEDIUM*)CoTaskMemAlloc(sizeof(STGMEDIUM)); michael@0: if (dataObj->GetData(&fe, stg2) != S_OK) { michael@0: fail("Data object did not provide arbitrary data upon request!"); michael@0: return NS_ERROR_UNEXPECTED; michael@0: } michael@0: michael@0: if (stg2->hGlobal != hg) { michael@0: fail("Arbitrary data was not returned properly!"); michael@0: return rv; michael@0: } michael@0: ReleaseStgMedium(stg2); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: // This function performs basic drop tests, testing a data object consisting michael@0: // of one transferable michael@0: nsresult Do_Test1() michael@0: { michael@0: nsresult rv = NS_OK; michael@0: nsresult workingrv; michael@0: michael@0: workingrv = Do_CheckOneFile(); michael@0: if (NS_FAILED(workingrv)) { michael@0: fail("Drag object tests failed on a single file"); michael@0: rv = NS_ERROR_UNEXPECTED; michael@0: } else { michael@0: passed("Successfully created a working file drag object!"); michael@0: } michael@0: michael@0: workingrv = Do_CheckOneString(); michael@0: if (NS_FAILED(workingrv)) { michael@0: fail("Drag object tests failed on a single string"); michael@0: rv = NS_ERROR_UNEXPECTED; michael@0: } else { michael@0: passed("Successfully created a working string drag object!"); michael@0: } michael@0: michael@0: workingrv = Do_CheckSetArbitraryData(false); michael@0: if (NS_FAILED(workingrv)) { michael@0: fail("Drag object tests failed on setting arbitrary data"); michael@0: rv = NS_ERROR_UNEXPECTED; michael@0: } else { michael@0: passed("Successfully set arbitrary data on a drag object"); michael@0: } michael@0: michael@0: return rv; michael@0: } michael@0: michael@0: // This function performs basic drop tests, testing a data object consisting of michael@0: // two transferables. michael@0: nsresult Do_Test2() michael@0: { michael@0: nsresult rv = NS_OK; michael@0: nsresult workingrv; michael@0: michael@0: workingrv = Do_CheckTwoFiles(); michael@0: if (NS_FAILED(workingrv)) { michael@0: fail("Drag object tests failed on multiple files"); michael@0: rv = NS_ERROR_UNEXPECTED; michael@0: } else { michael@0: passed("Successfully created a working multiple file drag object!"); michael@0: } michael@0: michael@0: workingrv = Do_CheckTwoStrings(); michael@0: if (NS_FAILED(workingrv)) { michael@0: fail("Drag object tests failed on multiple strings"); michael@0: rv = NS_ERROR_UNEXPECTED; michael@0: } else { michael@0: passed("Successfully created a working multiple string drag object!"); michael@0: } michael@0: michael@0: workingrv = Do_CheckSetArbitraryData(true); michael@0: if (NS_FAILED(workingrv)) { michael@0: fail("Drag object tests failed on setting arbitrary data"); michael@0: rv = NS_ERROR_UNEXPECTED; michael@0: } else { michael@0: passed("Successfully set arbitrary data on a drag object"); michael@0: } michael@0: michael@0: return rv; michael@0: } michael@0: michael@0: // This function performs advanced drag and drop tests, testing a data object michael@0: // consisting of multiple transferables that have different data types michael@0: nsresult Do_Test3() michael@0: { michael@0: nsresult rv = NS_OK; michael@0: nsresult workingrv; michael@0: michael@0: // XXX TODO Write more advanced tests in Bug 535860 michael@0: return rv; michael@0: } michael@0: michael@0: int main(int argc, char** argv) michael@0: { michael@0: ScopedXPCOM xpcom("Test Windows Drag and Drop"); michael@0: michael@0: nsCOMPtr file; michael@0: file = xpcom.GetProfileDirectory(); michael@0: xferFile = file; michael@0: michael@0: if (NS_SUCCEEDED(Do_Test1())) michael@0: passed("Basic Drag and Drop data type tests (single transferable) succeeded!"); michael@0: michael@0: if (NS_SUCCEEDED(Do_Test2())) michael@0: passed("Basic Drag and Drop data type tests (multiple transferables) succeeded!"); michael@0: michael@0: //if (NS_SUCCEEDED(Do_Test3())) michael@0: // passed("Advanced Drag and Drop data type tests succeeded!"); michael@0: michael@0: return gFailCount; michael@0: }