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 mozilla_widget_WinUtils_h__
7 #define mozilla_widget_WinUtils_h__
14 #include "nsAutoPtr.h"
18 #include "nsIRunnable.h"
19 #include "nsICryptoHash.h"
21 #include "nsIFaviconService.h"
23 #include "nsIDownloader.h"
25 #include "nsIWidget.h"
26 #include "nsIThread.h"
28 #include "mozilla/Attributes.h"
31 * NS_INLINE_DECL_IUNKNOWN_REFCOUNTING should be used for defining and
32 * implementing AddRef() and Release() of IUnknown interface.
33 * This depends on xpcom/glue/nsISupportsImpl.h.
36 #define NS_INLINE_DECL_IUNKNOWN_REFCOUNTING(_class) \
38 STDMETHODIMP_(ULONG) AddRef() \
40 MOZ_ASSERT_TYPE_OK_FOR_REFCOUNTING(_class) \
41 MOZ_ASSERT(int32_t(mRefCnt) >= 0, "illegal refcnt"); \
42 NS_ASSERT_OWNINGTHREAD(_class); \
44 NS_LOG_ADDREF(this, mRefCnt, #_class, sizeof(*this)); \
45 return static_cast<ULONG>(mRefCnt.get()); \
47 STDMETHODIMP_(ULONG) Release() \
49 MOZ_ASSERT(int32_t(mRefCnt) > 0, \
50 "Release called on object that has already been released!"); \
51 NS_ASSERT_OWNINGTHREAD(_class); \
53 NS_LOG_RELEASE(this, mRefCnt, #_class); \
55 NS_ASSERT_OWNINGTHREAD(_class); \
56 mRefCnt = 1; /* stabilize */ \
60 return static_cast<ULONG>(mRefCnt.get()); \
63 nsAutoRefCnt mRefCnt; \
64 NS_DECL_OWNINGTHREAD \
75 // Windows message debugging data
80 extern EventMsgInfo gAllEvents
[];
82 // More complete QS definitions for MsgWaitForMultipleObjects() and
83 // GetQueueStatus() that include newer win8 specific defines.
86 #define QS_RAWINPUT 0x0400
90 #define QS_TOUCH 0x0800
91 #define QS_POINTER 0x1000
94 #define MOZ_QS_ALLEVENT (QS_KEY | QS_MOUSEMOVE | QS_MOUSEBUTTON | \
95 QS_POSTMESSAGE | QS_TIMER | QS_PAINT | \
96 QS_SENDMESSAGE | QS_HOTKEY | \
97 QS_ALLPOSTMESSAGE | QS_RAWINPUT | \
98 QS_TOUCH | QS_POINTER)
101 #define LogFunction() mozilla::widget::WinUtils::Log(__FUNCTION__)
102 #define LogThread() mozilla::widget::WinUtils::Log("%s: IsMainThread:%d ThreadId:%X", __FUNCTION__, NS_IsMainThread(), GetCurrentThreadId())
103 #define LogThis() mozilla::widget::WinUtils::Log("[%X] %s", this, __FUNCTION__)
104 #define LogException(e) mozilla::widget::WinUtils::Log("%s Exception:%s", __FUNCTION__, e->ToString()->Data())
105 #define LogHRESULT(hr) mozilla::widget::WinUtils::Log("%s hr=%X", __FUNCTION__, hr)
108 class myDownloadObserver MOZ_FINAL
: public nsIDownloadObserver
110 ~myDownloadObserver() {}
114 NS_DECL_NSIDOWNLOADOBSERVER
121 * Functions to convert between logical pixels as used by most Windows APIs
122 * and physical (device) pixels.
124 static double LogToPhysFactor();
125 static double PhysToLogFactor();
126 static int32_t LogToPhys(double aValue
);
127 static double PhysToLog(int32_t aValue
);
130 * Logging helpers that dump output to prlog module 'Widget', console, and
131 * OutputDebugString. Note these output in both debug and release builds.
133 static void Log(const char *fmt
, ...);
134 static void LogW(const wchar_t *fmt
, ...);
137 * PeekMessage() and GetMessage() are wrapper methods for PeekMessageW(),
138 * GetMessageW(), ITfMessageMgr::PeekMessageW() and
139 * ITfMessageMgr::GetMessageW().
140 * Don't call the native APIs directly. You MUST use these methods instead.
142 static bool PeekMessage(LPMSG aMsg
, HWND aWnd
, UINT aFirstMessage
,
143 UINT aLastMessage
, UINT aOption
);
144 static bool GetMessage(LPMSG aMsg
, HWND aWnd
, UINT aFirstMessage
,
148 * Wait until a message is ready to be processed.
149 * Prefer using this method to directly calling ::WaitMessage since
150 * ::WaitMessage will wait if there is an unread message in the queue.
151 * That can cause freezes until another message enters the queue if the
152 * message is marked read by a call to PeekMessage which the caller is
153 * not aware of (e.g., from a different thread).
154 * Note that this method may cause sync dispatch of sent (as opposed to
156 * @param aTimeoutMs Timeout for waiting in ms, defaults to INFINITE
158 static void WaitForMessage(DWORD aTimeoutMs
= INFINITE
);
161 * Gets the value of a string-typed registry value.
163 * @param aRoot The registry root to search in.
164 * @param aKeyName The name of the registry key to open.
165 * @param aValueName The name of the registry value in the specified key whose
166 * value is to be retrieved. Can be null, to retrieve the key's unnamed/
168 * @param aBuffer The buffer into which to store the string value. Can be
169 * null, in which case the return value indicates just whether the value
171 * @param aBufferLength The size of aBuffer, in bytes.
172 * @return Whether the value exists and is a string.
174 static bool GetRegistryKey(HKEY aRoot
,
175 char16ptr_t aKeyName
,
176 char16ptr_t aValueName
,
178 DWORD aBufferLength
);
181 * Checks whether the registry key exists in either 32bit or 64bit branch on
184 * @param aRoot The registry root of aName.
185 * @param aKeyName The name of the registry key to check.
186 * @return TRUE if it exists and is readable. Otherwise, FALSE.
188 static bool HasRegistryKey(HKEY aRoot
,
189 char16ptr_t aKeyName
);
192 * GetTopLevelHWND() returns a window handle of the top level window which
193 * aWnd belongs to. Note that the result may not be our window, i.e., it
194 * may not be managed by nsWindow.
196 * See follwing table for the detail of the result window type.
198 * +-------------------------+-----------------------------------------------+
199 * | | aStopIfNotPopup |
200 * +-------------------------+-----------------------+-----------------------+
202 + +-----------------+-------+-----------------------+-----------------------+
203 * | | | * an independent top level window |
204 * | | TRUE | * a pupup window (WS_POPUP) |
205 * | | | * an owned top level window (like dialog) |
206 * | aStopIfNotChild +-------+-----------------------+-----------------------+
207 * | | | * independent window | * only an independent |
208 * | | FALSE | * non-popup-owned- | top level window |
209 * | | | window like dialog | |
210 * +-----------------+-------+-----------------------+-----------------------+
212 static HWND
GetTopLevelHWND(HWND aWnd
,
213 bool aStopIfNotChild
= false,
214 bool aStopIfNotPopup
= true);
217 * SetNSWindowBasePtr() associates an nsWindowBase to aWnd. If aWidget is
218 * nullptr, it dissociate any nsBaseWidget pointer from aWnd.
219 * GetNSWindowBasePtr() returns an nsWindowBase pointer which was associated by
220 * SetNSWindowBasePtr().
221 * GetNSWindowPtr() is a legacy api for win32 nsWindow and should be avoided
222 * outside of nsWindow src.
224 static bool SetNSWindowBasePtr(HWND aWnd
, nsWindowBase
* aWidget
);
225 static nsWindowBase
* GetNSWindowBasePtr(HWND aWnd
);
226 static nsWindow
* GetNSWindowPtr(HWND aWnd
);
229 * GetMonitorCount() returns count of monitors on the environment.
231 static int32_t GetMonitorCount();
234 * IsOurProcessWindow() returns TRUE if aWnd belongs our process.
237 static bool IsOurProcessWindow(HWND aWnd
);
240 * FindOurProcessWindow() returns the nearest ancestor window which
241 * belongs to our process. If it fails to find our process's window by the
242 * top level window, returns nullptr. And note that this is using
243 * ::GetParent() for climbing the window hierarchy, therefore, it gives
244 * up at an owned top level window except popup window (e.g., dialog).
246 static HWND
FindOurProcessWindow(HWND aWnd
);
249 * FindOurWindowAtPoint() returns the topmost child window which belongs to
250 * our process's top level window.
252 * NOTE: the topmost child window may NOT be our process's window like a
255 static HWND
FindOurWindowAtPoint(const POINT
& aPointInScreen
);
258 * InitMSG() returns an MSG struct which was initialized by the params.
259 * Don't trust the other members in the result.
261 static MSG
InitMSG(UINT aMessage
, WPARAM wParam
, LPARAM lParam
, HWND aWnd
);
264 * GetScanCode() returns a scan code for the LPARAM of WM_KEYDOWN, WM_KEYUP,
265 * WM_CHAR and WM_UNICHAR.
268 static WORD
GetScanCode(LPARAM aLParam
)
270 return (aLParam
>> 16) & 0xFF;
274 * IsExtendedScanCode() returns TRUE if the LPARAM indicates the key message
275 * is an extended key event.
277 static bool IsExtendedScanCode(LPARAM aLParam
)
279 return (aLParam
& 0x1000000) != 0;
283 * GetInternalMessage() converts a native message to an internal message.
284 * If there is no internal message for the given native message, returns
285 * the native message itself.
287 static UINT
GetInternalMessage(UINT aNativeMessage
);
290 * GetNativeMessage() converts an internal message to a native message.
291 * If aInternalMessage is a native message, returns the native message itself.
293 static UINT
GetNativeMessage(UINT aInternalMessage
);
296 * GetMouseInputSource() returns a pointing device information. The value is
297 * one of nsIDOMMouseEvent::MOZ_SOURCE_*. This method MUST be called during
298 * mouse message handling.
300 static uint16_t GetMouseInputSource();
302 static bool GetIsMouseFromTouch(uint32_t aEventType
);
305 * SHCreateItemFromParsingName() calls native SHCreateItemFromParsingName()
306 * API which is available on Vista and up.
308 static HRESULT
SHCreateItemFromParsingName(PCWSTR pszPath
, IBindCtx
*pbc
,
309 REFIID riid
, void **ppv
);
312 * SHGetKnownFolderPath() calls native SHGetKnownFolderPath()
313 * API which is available on Vista and up.
315 static HRESULT
SHGetKnownFolderPath(REFKNOWNFOLDERID rfid
,
320 * GetShellItemPath return the file or directory path of a shell item.
321 * Internally calls IShellItem's GetDisplayName.
323 * aItem the shell item containing the path.
324 * aResultString the resulting string path.
325 * returns true if a path was retreived.
327 static bool GetShellItemPath(IShellItem
* aItem
,
328 nsString
& aResultString
);
331 * ConvertHRGNToRegion converts a Windows HRGN to an nsIntRegion.
333 * aRgn the HRGN to convert.
334 * returns the nsIntRegion.
336 static nsIntRegion
ConvertHRGNToRegion(HRGN aRgn
);
339 * ToIntRect converts a Windows RECT to a nsIntRect.
341 * aRect the RECT to convert.
342 * returns the nsIntRect.
344 static nsIntRect
ToIntRect(const RECT
& aRect
);
347 * Returns true if the context or IME state is enabled. Otherwise, false.
349 static bool IsIMEEnabled(const InputContext
& aInputContext
);
350 static bool IsIMEEnabled(IMEState::Enabled aIMEState
);
353 * Returns modifier key array for aModifiers. This is for
354 * nsIWidget::SynthethizeNative*Event().
356 static void SetupKeyModifiersSequence(nsTArray
<KeyPair
>* aArray
,
357 uint32_t aModifiers
);
359 // dwmapi.dll function typedefs and declarations
360 typedef HRESULT (WINAPI
*DwmExtendFrameIntoClientAreaProc
)(HWND hWnd
, const MARGINS
*pMarInset
);
361 typedef HRESULT (WINAPI
*DwmIsCompositionEnabledProc
)(BOOL
*pfEnabled
);
362 typedef HRESULT (WINAPI
*DwmSetIconicThumbnailProc
)(HWND hWnd
, HBITMAP hBitmap
, DWORD dwSITFlags
);
363 typedef HRESULT (WINAPI
*DwmSetIconicLivePreviewBitmapProc
)(HWND hWnd
, HBITMAP hBitmap
, POINT
*pptClient
, DWORD dwSITFlags
);
364 typedef HRESULT (WINAPI
*DwmGetWindowAttributeProc
)(HWND hWnd
, DWORD dwAttribute
, LPCVOID pvAttribute
, DWORD cbAttribute
);
365 typedef HRESULT (WINAPI
*DwmSetWindowAttributeProc
)(HWND hWnd
, DWORD dwAttribute
, LPCVOID pvAttribute
, DWORD cbAttribute
);
366 typedef HRESULT (WINAPI
*DwmInvalidateIconicBitmapsProc
)(HWND hWnd
);
367 typedef HRESULT (WINAPI
*DwmDefWindowProcProc
)(HWND hWnd
, UINT msg
, LPARAM lParam
, WPARAM wParam
, LRESULT
*aRetValue
);
368 typedef HRESULT (WINAPI
*DwmGetCompositionTimingInfoProc
)(HWND hWnd
, DWM_TIMING_INFO
*info
);
370 static DwmExtendFrameIntoClientAreaProc dwmExtendFrameIntoClientAreaPtr
;
371 static DwmIsCompositionEnabledProc dwmIsCompositionEnabledPtr
;
372 static DwmSetIconicThumbnailProc dwmSetIconicThumbnailPtr
;
373 static DwmSetIconicLivePreviewBitmapProc dwmSetIconicLivePreviewBitmapPtr
;
374 static DwmGetWindowAttributeProc dwmGetWindowAttributePtr
;
375 static DwmSetWindowAttributeProc dwmSetWindowAttributePtr
;
376 static DwmInvalidateIconicBitmapsProc dwmInvalidateIconicBitmapsPtr
;
377 static DwmDefWindowProcProc dwmDwmDefWindowProcPtr
;
378 static DwmGetCompositionTimingInfoProc dwmGetCompositionTimingInfoPtr
;
380 static void Initialize();
382 static bool ShouldHideScrollbars();
385 typedef HRESULT (WINAPI
* SHCreateItemFromParsingNamePtr
)(PCWSTR pszPath
,
389 static SHCreateItemFromParsingNamePtr sCreateItemFromParsingName
;
390 typedef HRESULT (WINAPI
* SHGetKnownFolderPathPtr
)(REFKNOWNFOLDERID rfid
,
394 static SHGetKnownFolderPathPtr sGetKnownFolderPath
;
398 class AsyncFaviconDataReady MOZ_FINAL
: public nsIFaviconDataCallback
402 NS_DECL_NSIFAVICONDATACALLBACK
404 AsyncFaviconDataReady(nsIURI
*aNewURI
,
405 nsCOMPtr
<nsIThread
> &aIOThread
,
406 const bool aURLShortcut
);
407 nsresult
OnFaviconDataNotAvailable(void);
409 ~AsyncFaviconDataReady() {}
411 nsCOMPtr
<nsIURI
> mNewURI
;
412 nsCOMPtr
<nsIThread
> mIOThread
;
413 const bool mURLShortcut
;
418 * Asynchronously tries add the list to the build
420 class AsyncEncodeAndWriteIcon
: public nsIRunnable
423 const bool mURLShortcut
;
424 NS_DECL_THREADSAFE_ISUPPORTS
427 // Warning: AsyncEncodeAndWriteIcon assumes ownership of the aData buffer passed in
428 AsyncEncodeAndWriteIcon(const nsAString
&aIconPath
,
429 uint8_t *aData
, uint32_t aDataLen
, uint32_t aStride
,
430 uint32_t aWidth
, uint32_t aHeight
,
431 const bool aURLShortcut
);
434 virtual ~AsyncEncodeAndWriteIcon();
436 nsAutoString mIconPath
;
437 nsAutoArrayPtr
<uint8_t> mBuffer
;
439 uint32_t mBufferLength
;
446 class AsyncDeleteIconFromDisk
: public nsIRunnable
449 NS_DECL_THREADSAFE_ISUPPORTS
452 AsyncDeleteIconFromDisk(const nsAString
&aIconPath
);
455 virtual ~AsyncDeleteIconFromDisk();
457 nsAutoString mIconPath
;
460 class AsyncDeleteAllFaviconsFromDisk
: public nsIRunnable
463 NS_DECL_THREADSAFE_ISUPPORTS
466 AsyncDeleteAllFaviconsFromDisk(bool aIgnoreRecent
= false);
469 virtual ~AsyncDeleteAllFaviconsFromDisk();
471 int32_t mIcoNoDeleteSeconds
;
478 static const char kJumpListCacheDir
[];
479 static const char kShortcutCacheDir
[];
480 static nsresult
ObtainCachedIconFile(nsCOMPtr
<nsIURI
> aFaviconPageURI
,
481 nsString
&aICOFilePath
,
482 nsCOMPtr
<nsIThread
> &aIOThread
,
485 static nsresult
HashURI(nsCOMPtr
<nsICryptoHash
> &aCryptoHash
,
487 nsACString
& aUriHash
);
489 static nsresult
GetOutputIconPath(nsCOMPtr
<nsIURI
> aFaviconPageURI
,
490 nsCOMPtr
<nsIFile
> &aICOFile
,
494 CacheIconFileFromFaviconURIAsync(nsCOMPtr
<nsIURI
> aFaviconPageURI
,
495 nsCOMPtr
<nsIFile
> aICOFile
,
496 nsCOMPtr
<nsIThread
> &aIOThread
,
499 static int32_t GetICOCacheSecondsTimeout();
504 } // namespace widget
505 } // namespace mozilla
507 #endif // mozilla_widget_WinUtils_h__