Bug 1799258 - Fix constexpr issue on base toolchain builds. r=gfx-reviewers,lsalzman
[gecko.git] / widget / windows / nsDataObj.h
blob4ba5f92f591e5ce1c625b3f505d7a80b850d4096
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #ifndef _NSDATAOBJ_H_
7 #define _NSDATAOBJ_H_
9 #include <oleidl.h>
10 #include <shldisp.h>
12 #include "mozilla/glue/WinUtils.h"
13 #include "mozilla/LazyIdleThread.h"
14 #include "nsCOMPtr.h"
15 #include "nsString.h"
16 #include "nsIFile.h"
17 #include "nsIURI.h"
18 #include "nsIStreamListener.h"
19 #include "nsIChannel.h"
20 #include "nsCOMArray.h"
21 #include "nsITimer.h"
22 #include "nsIURI.h"
23 #include "nsString.h"
24 #include "nsWindowsHelpers.h"
26 class nsICookieJarSettings;
27 class nsIThread;
28 class nsIPrincipal;
29 class CEnumFormatEtc;
30 class nsITransferable;
33 * This ole registered class is used to facilitate drag-drop of objects which
34 * can be adapted by an object derived from CfDragDrop. The CfDragDrop is
35 * associated with instances via SetDragDrop().
37 class nsDataObj : public IDataObject, public IDataObjectAsyncCapability {
38 RefPtr<mozilla::LazyIdleThread> mIOThread;
40 public: // construction, destruction
41 explicit nsDataObj(nsIURI* uri = nullptr);
43 protected:
44 virtual ~nsDataObj();
46 public: // IUnknown methods - see iunknown.h for documentation
47 STDMETHODIMP_(ULONG) AddRef() override;
48 STDMETHODIMP QueryInterface(REFIID, void**) override;
49 STDMETHODIMP_(ULONG) Release() override;
51 // support for clipboard
52 virtual void AddDataFlavor(const char* aDataFlavor, LPFORMATETC aFE);
53 void SetTransferable(nsITransferable* aTransferable);
55 public: // IDataObject methods - these are general comments. see CfDragDrop
56 // for overriding behavior
57 // Store data in pSTM according to the format specified by pFE, if the
58 // format is supported (supported formats are specified in CfDragDrop::
59 // GetFormats) and return NOERROR; otherwise return DATA_E_FORMATETC. It
60 // is the callers responsibility to free pSTM if NOERROR is returned.
61 STDMETHODIMP GetData(LPFORMATETC pFE, LPSTGMEDIUM pSTM) override;
63 // Similar to GetData except that the caller allocates the structure
64 // referenced by pSTM.
65 STDMETHODIMP GetDataHere(LPFORMATETC pFE, LPSTGMEDIUM pSTM) override;
67 // Returns S_TRUE if this object supports the format specified by pSTM,
68 // S_FALSE otherwise.
69 STDMETHODIMP QueryGetData(LPFORMATETC pFE) override;
71 // Set pCanonFE to the canonical format of pFE if one exists and return
72 // NOERROR, otherwise return DATA_S_SAMEFORMATETC. A canonical format
73 // implies an identical rendering.
74 STDMETHODIMP GetCanonicalFormatEtc(LPFORMATETC pFE,
75 LPFORMATETC pCanonFE) final;
77 // Set this objects data according to the format specified by pFE and
78 // the storage medium specified by pSTM and return NOERROR, if the format
79 // is supported. If release is TRUE this object must release the storage
80 // associated with pSTM.
81 STDMETHODIMP SetData(LPFORMATETC pFE, LPSTGMEDIUM pSTM,
82 BOOL release) override;
84 // Set ppEnum to an IEnumFORMATETC object which will iterate all of the
85 // data formats that this object supports. direction is either DATADIR_GET
86 // or DATADIR_SET.
87 STDMETHODIMP EnumFormatEtc(DWORD direction, LPENUMFORMATETC* ppEnum) final;
89 // Set up an advisory connection to this object based on the format specified
90 // by pFE, flags, and the pAdvise. Set pConn to the established advise
91 // connection.
92 STDMETHODIMP DAdvise(LPFORMATETC pFE, DWORD flags, LPADVISESINK pAdvise,
93 DWORD* pConn) final;
95 // Turn off advising of a previous call to DAdvise which set pConn.
96 STDMETHODIMP DUnadvise(DWORD pConn) final;
98 // Set ppEnum to an IEnumSTATDATA object which will iterate over the
99 // existing objects which have established advisory connections to this
100 // object.
101 STDMETHODIMP EnumDAdvise(LPENUMSTATDATA* ppEnum) final;
103 // IDataObjectAsyncCapability methods
104 STDMETHODIMP EndOperation(HRESULT hResult, IBindCtx* pbcReserved,
105 DWORD dwEffects) final;
106 STDMETHODIMP GetAsyncMode(BOOL* pfIsOpAsync) final;
107 STDMETHODIMP InOperation(BOOL* pfInAsyncOp) final;
108 STDMETHODIMP SetAsyncMode(BOOL fDoOpAsync) final;
109 STDMETHODIMP StartOperation(IBindCtx* pbcReserved) final;
111 private: // other methods
112 // Gets the filename from the kFilePromiseURLMime flavour
113 HRESULT GetDownloadDetails(nsIURI** aSourceURI, nsAString& aFilename);
115 // help determine the kind of drag
116 bool IsFlavourPresent(const char* inFlavour);
118 protected:
119 HRESULT GetFile(FORMATETC& aFE, STGMEDIUM& aSTG);
120 HRESULT GetText(const nsACString& aDF, FORMATETC& aFE, STGMEDIUM& aSTG);
122 private:
123 HRESULT GetDib(const nsACString& inFlavor, FORMATETC&, STGMEDIUM& aSTG);
125 HRESULT DropImage(FORMATETC& aFE, STGMEDIUM& aSTG);
126 HRESULT DropFile(FORMATETC& aFE, STGMEDIUM& aSTG);
127 HRESULT DropTempFile(FORMATETC& aFE, STGMEDIUM& aSTG);
129 HRESULT GetUniformResourceLocator(FORMATETC& aFE, STGMEDIUM& aSTG,
130 bool aIsUnicode);
131 HRESULT ExtractUniformResourceLocatorA(FORMATETC& aFE, STGMEDIUM& aSTG);
132 HRESULT ExtractUniformResourceLocatorW(FORMATETC& aFE, STGMEDIUM& aSTG);
133 HRESULT GetFileDescriptor(FORMATETC& aFE, STGMEDIUM& aSTG, bool aIsUnicode);
135 protected:
136 HRESULT GetFileContents(FORMATETC& aFE, STGMEDIUM& aSTG);
138 private:
139 HRESULT GetPreferredDropEffect(FORMATETC& aFE, STGMEDIUM& aSTG);
141 // Provide the structures needed for an internet shortcut by the shell
142 HRESULT GetFileDescriptorInternetShortcutA(FORMATETC& aFE, STGMEDIUM& aSTG);
143 HRESULT GetFileDescriptorInternetShortcutW(FORMATETC& aFE, STGMEDIUM& aSTG);
144 HRESULT GetFileContentsInternetShortcut(FORMATETC& aFE, STGMEDIUM& aSTG);
146 // IStream implementation
147 HRESULT GetFileDescriptor_IStreamA(FORMATETC& aFE, STGMEDIUM& aSTG);
148 HRESULT GetFileDescriptor_IStreamW(FORMATETC& aFE, STGMEDIUM& aSTG);
149 HRESULT GetFileContents_IStream(FORMATETC& aFE, STGMEDIUM& aSTG);
151 nsresult ExtractShortcutURL(nsString& outURL);
152 nsresult ExtractShortcutTitle(nsString& outTitle);
154 // munge our HTML data to win32's CF_HTML spec. Will null terminate
155 nsresult BuildPlatformHTML(const char* inOurHTML, char** outPlatformHTML);
157 // Used for the SourceURL part of CF_HTML
158 nsCString mSourceURL;
160 protected:
161 BOOL FormatsMatch(const FORMATETC& source, const FORMATETC& target) const;
163 ULONG m_cRef; // the reference count
165 private:
166 nsTArray<nsCString> mDataFlavors;
168 nsITransferable* mTransferable; // nsDataObj owns and ref counts
169 // nsITransferable, the nsITransferable does
170 // know anything about the nsDataObj
172 protected:
173 CEnumFormatEtc* m_enumFE; // Ownership Rules:
174 // nsDataObj owns and ref counts CEnumFormatEtc,
176 private:
177 nsCOMPtr<nsIFile> mCachedTempFile;
178 RefPtr<nsDataObj> mKeepAlive;
180 BOOL mIsAsyncMode;
181 BOOL mIsInOperation;
182 ///////////////////////////////////////////////////////////////////////////////
183 // CStream class implementation
184 // this class is used in Drag and drop with download sample
185 // called from IDataObject::GetData
186 class CStreamBase : public IStream {
187 // IStream
188 STDMETHODIMP Clone(IStream** ppStream) final;
189 STDMETHODIMP Commit(DWORD dwFrags) final;
190 STDMETHODIMP CopyTo(IStream* pDestStream, ULARGE_INTEGER nBytesToCopy,
191 ULARGE_INTEGER* nBytesRead,
192 ULARGE_INTEGER* nBytesWritten) final;
193 STDMETHODIMP LockRegion(ULARGE_INTEGER nStart, ULARGE_INTEGER nBytes,
194 DWORD dwFlags) final;
195 STDMETHODIMP Revert(void) final;
196 STDMETHODIMP Seek(LARGE_INTEGER nMove, DWORD dwOrigin,
197 ULARGE_INTEGER* nNewPos) final;
198 STDMETHODIMP SetSize(ULARGE_INTEGER nNewSize) final;
199 STDMETHODIMP UnlockRegion(ULARGE_INTEGER nStart, ULARGE_INTEGER nBytes,
200 DWORD dwFlags) final;
201 STDMETHODIMP Write(const void* pvBuffer, ULONG nBytesToRead,
202 ULONG* nBytesRead) final;
204 protected:
205 uint32_t mStreamRead;
207 CStreamBase();
208 virtual ~CStreamBase();
211 class CStream final : public CStreamBase, public nsIStreamListener {
212 nsCOMPtr<nsIChannel> mChannel;
213 FallibleTArray<uint8_t> mChannelData;
214 nsresult mChannelResult;
215 bool mChannelRead;
217 virtual ~CStream();
218 nsresult WaitForCompletion();
220 // IUnknown
221 STDMETHOD(QueryInterface)(REFIID refiid, void** ppvResult) final;
223 // IStream
224 STDMETHODIMP Read(void* pvBuffer, ULONG nBytesToRead,
225 ULONG* nBytesRead) final;
226 STDMETHODIMP Stat(STATSTG* statstg, DWORD dwFlags) final;
228 public:
229 CStream();
230 nsresult Init(nsIURI* pSourceURI, nsContentPolicyType aContentPolicyType,
231 nsIPrincipal* aRequestingPrincipal,
232 nsICookieJarSettings* aCookieJarSettings);
234 NS_DECL_ISUPPORTS
235 NS_DECL_NSIREQUESTOBSERVER
236 NS_DECL_NSISTREAMLISTENER
239 HRESULT CreateStream(IStream** outStream);
241 // This class must be thread-safe.
242 class AutoCloseEvent final {
243 const nsAutoHandle mEvent;
245 AutoCloseEvent(const AutoCloseEvent&) = delete;
246 void operator=(const AutoCloseEvent&) = delete;
247 ~AutoCloseEvent() = default;
249 public:
250 AutoCloseEvent();
251 bool IsInited() const;
252 void Signal() const;
253 DWORD Wait(DWORD aMillisec) const;
254 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AutoCloseEvent)
257 // This class must be thread-safe.
258 class AutoSetEvent final {
259 const RefPtr<AutoCloseEvent> mEvent;
261 AutoSetEvent(const AutoSetEvent&) = delete;
262 void operator=(const AutoSetEvent&) = delete;
263 ~AutoSetEvent();
265 public:
266 explicit AutoSetEvent(mozilla::NotNull<AutoCloseEvent*> aEvent);
267 void Signal() const;
268 bool IsWaiting() const;
269 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AutoSetEvent)
272 // This class must be thread-safe.
273 class CMemStream final : public CStreamBase {
274 static mozilla::glue::Win32SRWLock mLock;
275 const nsAutoGlobalMem mGlobalMem;
276 const RefPtr<AutoCloseEvent> mEvent;
277 const uint32_t mTotalLength;
278 RefPtr<IUnknown> mMarshaler;
280 virtual ~CMemStream();
281 void WaitForCompletion();
283 // IStream
284 STDMETHODIMP Read(void* pvBuffer, ULONG nBytesToRead,
285 ULONG* nBytesRead) final;
286 STDMETHODIMP Stat(STATSTG* statstg, DWORD dwFlags) final;
288 public:
289 CMemStream(nsHGLOBAL aGlobalMem, uint32_t mTotalLength,
290 already_AddRefed<AutoCloseEvent> aEvent);
292 // IUnknown
293 STDMETHOD(QueryInterface)(REFIID refiid, void** ppvResult) final;
294 NS_INLINE_DECL_THREADSAFE_VIRTUAL_REFCOUNTING(CMemStream, final)
297 private:
298 // Drag and drop helper data for implementing drag and drop image support
299 typedef struct {
300 FORMATETC fe;
301 STGMEDIUM stgm;
302 } DATAENTRY, *LPDATAENTRY;
304 nsTArray<LPDATAENTRY> mDataEntryList;
305 nsCOMPtr<nsITimer> mTimer;
307 bool LookupArbitraryFormat(FORMATETC* aFormat, LPDATAENTRY* aDataEntry,
308 BOOL aAddorUpdate);
309 bool CopyMediumData(STGMEDIUM* aMediumDst, STGMEDIUM* aMediumSrc,
310 LPFORMATETC aFormat, BOOL aSetData);
313 #endif // _NSDATAOBJ_H_