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: michael@0: #ifndef mozilla_widget_WinUtils_h__ michael@0: #define mozilla_widget_WinUtils_h__ michael@0: michael@0: #include "nscore.h" michael@0: #include michael@0: #include michael@0: #include michael@0: #include michael@0: #include "nsAutoPtr.h" michael@0: #include "nsString.h" michael@0: #include "nsRegion.h" michael@0: michael@0: #include "nsIRunnable.h" michael@0: #include "nsICryptoHash.h" michael@0: #ifdef MOZ_PLACES michael@0: #include "nsIFaviconService.h" michael@0: #endif michael@0: #include "nsIDownloader.h" michael@0: #include "nsIURI.h" michael@0: #include "nsIWidget.h" michael@0: michael@0: #include "mozilla/Attributes.h" michael@0: michael@0: class nsWindow; michael@0: class nsWindowBase; michael@0: struct KeyPair; michael@0: struct nsIntRect; michael@0: class nsIThread; michael@0: michael@0: namespace mozilla { michael@0: namespace widget { michael@0: michael@0: // More complete QS definitions for MsgWaitForMultipleObjects() and michael@0: // GetQueueStatus() that include newer win8 specific defines. michael@0: michael@0: #ifndef QS_RAWINPUT michael@0: #define QS_RAWINPUT 0x0400 michael@0: #endif michael@0: michael@0: #ifndef QS_TOUCH michael@0: #define QS_TOUCH 0x0800 michael@0: #define QS_POINTER 0x1000 michael@0: #endif michael@0: michael@0: #define MOZ_QS_ALLEVENT (QS_KEY | QS_MOUSEMOVE | QS_MOUSEBUTTON | \ michael@0: QS_POSTMESSAGE | QS_TIMER | QS_PAINT | \ michael@0: QS_SENDMESSAGE | QS_HOTKEY | \ michael@0: QS_ALLPOSTMESSAGE | QS_RAWINPUT | \ michael@0: QS_TOUCH | QS_POINTER) michael@0: michael@0: // Logging macros michael@0: #define LogFunction() mozilla::widget::WinUtils::Log(__FUNCTION__) michael@0: #define LogThread() mozilla::widget::WinUtils::Log("%s: IsMainThread:%d ThreadId:%X", __FUNCTION__, NS_IsMainThread(), GetCurrentThreadId()) michael@0: #define LogThis() mozilla::widget::WinUtils::Log("[%X] %s", this, __FUNCTION__) michael@0: #define LogException(e) mozilla::widget::WinUtils::Log("%s Exception:%s", __FUNCTION__, e->ToString()->Data()) michael@0: #define LogHRESULT(hr) mozilla::widget::WinUtils::Log("%s hr=%X", __FUNCTION__, hr) michael@0: michael@0: class myDownloadObserver MOZ_FINAL : public nsIDownloadObserver michael@0: { michael@0: public: michael@0: NS_DECL_ISUPPORTS michael@0: NS_DECL_NSIDOWNLOADOBSERVER michael@0: }; michael@0: michael@0: class WinUtils { michael@0: public: michael@0: /** michael@0: * Functions to convert between logical pixels as used by most Windows APIs michael@0: * and physical (device) pixels. michael@0: */ michael@0: static double LogToPhysFactor(); michael@0: static double PhysToLogFactor(); michael@0: static int32_t LogToPhys(double aValue); michael@0: static double PhysToLog(int32_t aValue); michael@0: michael@0: /** michael@0: * Logging helpers that dump output to prlog module 'Widget', console, and michael@0: * OutputDebugString. Note these output in both debug and release builds. michael@0: */ michael@0: static void Log(const char *fmt, ...); michael@0: static void LogW(const wchar_t *fmt, ...); michael@0: michael@0: /** michael@0: * PeekMessage() and GetMessage() are wrapper methods for PeekMessageW(), michael@0: * GetMessageW(), ITfMessageMgr::PeekMessageW() and michael@0: * ITfMessageMgr::GetMessageW(). michael@0: * Don't call the native APIs directly. You MUST use these methods instead. michael@0: */ michael@0: static bool PeekMessage(LPMSG aMsg, HWND aWnd, UINT aFirstMessage, michael@0: UINT aLastMessage, UINT aOption); michael@0: static bool GetMessage(LPMSG aMsg, HWND aWnd, UINT aFirstMessage, michael@0: UINT aLastMessage); michael@0: /** michael@0: * Gets the value of a string-typed registry value. michael@0: * michael@0: * @param aRoot The registry root to search in. michael@0: * @param aKeyName The name of the registry key to open. michael@0: * @param aValueName The name of the registry value in the specified key whose michael@0: * value is to be retrieved. Can be null, to retrieve the key's unnamed/ michael@0: * default value. michael@0: * @param aBuffer The buffer into which to store the string value. Can be michael@0: * null, in which case the return value indicates just whether the value michael@0: * exists. michael@0: * @param aBufferLength The size of aBuffer, in bytes. michael@0: * @return Whether the value exists and is a string. michael@0: */ michael@0: static bool GetRegistryKey(HKEY aRoot, michael@0: char16ptr_t aKeyName, michael@0: char16ptr_t aValueName, michael@0: wchar_t* aBuffer, michael@0: DWORD aBufferLength); michael@0: michael@0: /** michael@0: * Checks whether the registry key exists in either 32bit or 64bit branch on michael@0: * the environment. michael@0: * michael@0: * @param aRoot The registry root of aName. michael@0: * @param aKeyName The name of the registry key to check. michael@0: * @return TRUE if it exists and is readable. Otherwise, FALSE. michael@0: */ michael@0: static bool HasRegistryKey(HKEY aRoot, michael@0: char16ptr_t aKeyName); michael@0: michael@0: /** michael@0: * GetTopLevelHWND() returns a window handle of the top level window which michael@0: * aWnd belongs to. Note that the result may not be our window, i.e., it michael@0: * may not be managed by nsWindow. michael@0: * michael@0: * See follwing table for the detail of the result window type. michael@0: * michael@0: * +-------------------------+-----------------------------------------------+ michael@0: * | | aStopIfNotPopup | michael@0: * +-------------------------+-----------------------+-----------------------+ michael@0: * | | TRUE | FALSE | michael@0: + +-----------------+-------+-----------------------+-----------------------+ michael@0: * | | | * an independent top level window | michael@0: * | | TRUE | * a pupup window (WS_POPUP) | michael@0: * | | | * an owned top level window (like dialog) | michael@0: * | aStopIfNotChild +-------+-----------------------+-----------------------+ michael@0: * | | | * independent window | * only an independent | michael@0: * | | FALSE | * non-popup-owned- | top level window | michael@0: * | | | window like dialog | | michael@0: * +-----------------+-------+-----------------------+-----------------------+ michael@0: */ michael@0: static HWND GetTopLevelHWND(HWND aWnd, michael@0: bool aStopIfNotChild = false, michael@0: bool aStopIfNotPopup = true); michael@0: michael@0: /** michael@0: * SetNSWindowBasePtr() associates an nsWindowBase to aWnd. If aWidget is michael@0: * nullptr, it dissociate any nsBaseWidget pointer from aWnd. michael@0: * GetNSWindowBasePtr() returns an nsWindowBase pointer which was associated by michael@0: * SetNSWindowBasePtr(). michael@0: * GetNSWindowPtr() is a legacy api for win32 nsWindow and should be avoided michael@0: * outside of nsWindow src. michael@0: */ michael@0: static bool SetNSWindowBasePtr(HWND aWnd, nsWindowBase* aWidget); michael@0: static nsWindowBase* GetNSWindowBasePtr(HWND aWnd); michael@0: static nsWindow* GetNSWindowPtr(HWND aWnd); michael@0: michael@0: /** michael@0: * GetMonitorCount() returns count of monitors on the environment. michael@0: */ michael@0: static int32_t GetMonitorCount(); michael@0: michael@0: /** michael@0: * IsOurProcessWindow() returns TRUE if aWnd belongs our process. michael@0: * Otherwise, FALSE. michael@0: */ michael@0: static bool IsOurProcessWindow(HWND aWnd); michael@0: michael@0: /** michael@0: * FindOurProcessWindow() returns the nearest ancestor window which michael@0: * belongs to our process. If it fails to find our process's window by the michael@0: * top level window, returns nullptr. And note that this is using michael@0: * ::GetParent() for climbing the window hierarchy, therefore, it gives michael@0: * up at an owned top level window except popup window (e.g., dialog). michael@0: */ michael@0: static HWND FindOurProcessWindow(HWND aWnd); michael@0: michael@0: /** michael@0: * FindOurWindowAtPoint() returns the topmost child window which belongs to michael@0: * our process's top level window. michael@0: * michael@0: * NOTE: the topmost child window may NOT be our process's window like a michael@0: * plugin's window. michael@0: */ michael@0: static HWND FindOurWindowAtPoint(const POINT& aPointInScreen); michael@0: michael@0: /** michael@0: * InitMSG() returns an MSG struct which was initialized by the params. michael@0: * Don't trust the other members in the result. michael@0: */ michael@0: static MSG InitMSG(UINT aMessage, WPARAM wParam, LPARAM lParam, HWND aWnd); michael@0: michael@0: /** michael@0: * GetScanCode() returns a scan code for the LPARAM of WM_KEYDOWN, WM_KEYUP, michael@0: * WM_CHAR and WM_UNICHAR. michael@0: * michael@0: */ michael@0: static WORD GetScanCode(LPARAM aLParam) michael@0: { michael@0: return (aLParam >> 16) & 0xFF; michael@0: } michael@0: michael@0: /** michael@0: * IsExtendedScanCode() returns TRUE if the LPARAM indicates the key message michael@0: * is an extended key event. michael@0: */ michael@0: static bool IsExtendedScanCode(LPARAM aLParam) michael@0: { michael@0: return (aLParam & 0x1000000) != 0; michael@0: } michael@0: michael@0: /** michael@0: * GetInternalMessage() converts a native message to an internal message. michael@0: * If there is no internal message for the given native message, returns michael@0: * the native message itself. michael@0: */ michael@0: static UINT GetInternalMessage(UINT aNativeMessage); michael@0: michael@0: /** michael@0: * GetNativeMessage() converts an internal message to a native message. michael@0: * If aInternalMessage is a native message, returns the native message itself. michael@0: */ michael@0: static UINT GetNativeMessage(UINT aInternalMessage); michael@0: michael@0: /** michael@0: * GetMouseInputSource() returns a pointing device information. The value is michael@0: * one of nsIDOMMouseEvent::MOZ_SOURCE_*. This method MUST be called during michael@0: * mouse message handling. michael@0: */ michael@0: static uint16_t GetMouseInputSource(); michael@0: michael@0: static bool GetIsMouseFromTouch(uint32_t aEventType); michael@0: michael@0: /** michael@0: * SHCreateItemFromParsingName() calls native SHCreateItemFromParsingName() michael@0: * API which is available on Vista and up. michael@0: */ michael@0: static HRESULT SHCreateItemFromParsingName(PCWSTR pszPath, IBindCtx *pbc, michael@0: REFIID riid, void **ppv); michael@0: michael@0: /** michael@0: * SHGetKnownFolderPath() calls native SHGetKnownFolderPath() michael@0: * API which is available on Vista and up. michael@0: */ michael@0: static HRESULT SHGetKnownFolderPath(REFKNOWNFOLDERID rfid, michael@0: DWORD dwFlags, michael@0: HANDLE hToken, michael@0: PWSTR *ppszPath); michael@0: /** michael@0: * GetShellItemPath return the file or directory path of a shell item. michael@0: * Internally calls IShellItem's GetDisplayName. michael@0: * michael@0: * aItem the shell item containing the path. michael@0: * aResultString the resulting string path. michael@0: * returns true if a path was retreived. michael@0: */ michael@0: static bool GetShellItemPath(IShellItem* aItem, michael@0: nsString& aResultString); michael@0: michael@0: /** michael@0: * ConvertHRGNToRegion converts a Windows HRGN to an nsIntRegion. michael@0: * michael@0: * aRgn the HRGN to convert. michael@0: * returns the nsIntRegion. michael@0: */ michael@0: static nsIntRegion ConvertHRGNToRegion(HRGN aRgn); michael@0: michael@0: /** michael@0: * ToIntRect converts a Windows RECT to a nsIntRect. michael@0: * michael@0: * aRect the RECT to convert. michael@0: * returns the nsIntRect. michael@0: */ michael@0: static nsIntRect ToIntRect(const RECT& aRect); michael@0: michael@0: /** michael@0: * Returns true if the context or IME state is enabled. Otherwise, false. michael@0: */ michael@0: static bool IsIMEEnabled(const InputContext& aInputContext); michael@0: static bool IsIMEEnabled(IMEState::Enabled aIMEState); michael@0: michael@0: /** michael@0: * Returns modifier key array for aModifiers. This is for michael@0: * nsIWidget::SynthethizeNative*Event(). michael@0: */ michael@0: static void SetupKeyModifiersSequence(nsTArray* aArray, michael@0: uint32_t aModifiers); michael@0: michael@0: // dwmapi.dll function typedefs and declarations michael@0: typedef HRESULT (WINAPI*DwmExtendFrameIntoClientAreaProc)(HWND hWnd, const MARGINS *pMarInset); michael@0: typedef HRESULT (WINAPI*DwmIsCompositionEnabledProc)(BOOL *pfEnabled); michael@0: typedef HRESULT (WINAPI*DwmSetIconicThumbnailProc)(HWND hWnd, HBITMAP hBitmap, DWORD dwSITFlags); michael@0: typedef HRESULT (WINAPI*DwmSetIconicLivePreviewBitmapProc)(HWND hWnd, HBITMAP hBitmap, POINT *pptClient, DWORD dwSITFlags); michael@0: typedef HRESULT (WINAPI*DwmGetWindowAttributeProc)(HWND hWnd, DWORD dwAttribute, LPCVOID pvAttribute, DWORD cbAttribute); michael@0: typedef HRESULT (WINAPI*DwmSetWindowAttributeProc)(HWND hWnd, DWORD dwAttribute, LPCVOID pvAttribute, DWORD cbAttribute); michael@0: typedef HRESULT (WINAPI*DwmInvalidateIconicBitmapsProc)(HWND hWnd); michael@0: typedef HRESULT (WINAPI*DwmDefWindowProcProc)(HWND hWnd, UINT msg, LPARAM lParam, WPARAM wParam, LRESULT *aRetValue); michael@0: typedef HRESULT (WINAPI*DwmGetCompositionTimingInfoProc)(HWND hWnd, DWM_TIMING_INFO *info); michael@0: michael@0: static DwmExtendFrameIntoClientAreaProc dwmExtendFrameIntoClientAreaPtr; michael@0: static DwmIsCompositionEnabledProc dwmIsCompositionEnabledPtr; michael@0: static DwmSetIconicThumbnailProc dwmSetIconicThumbnailPtr; michael@0: static DwmSetIconicLivePreviewBitmapProc dwmSetIconicLivePreviewBitmapPtr; michael@0: static DwmGetWindowAttributeProc dwmGetWindowAttributePtr; michael@0: static DwmSetWindowAttributeProc dwmSetWindowAttributePtr; michael@0: static DwmInvalidateIconicBitmapsProc dwmInvalidateIconicBitmapsPtr; michael@0: static DwmDefWindowProcProc dwmDwmDefWindowProcPtr; michael@0: static DwmGetCompositionTimingInfoProc dwmGetCompositionTimingInfoPtr; michael@0: michael@0: static void Initialize(); michael@0: michael@0: static bool ShouldHideScrollbars(); michael@0: michael@0: private: michael@0: typedef HRESULT (WINAPI * SHCreateItemFromParsingNamePtr)(PCWSTR pszPath, michael@0: IBindCtx *pbc, michael@0: REFIID riid, michael@0: void **ppv); michael@0: static SHCreateItemFromParsingNamePtr sCreateItemFromParsingName; michael@0: typedef HRESULT (WINAPI * SHGetKnownFolderPathPtr)(REFKNOWNFOLDERID rfid, michael@0: DWORD dwFlags, michael@0: HANDLE hToken, michael@0: PWSTR *ppszPath); michael@0: static SHGetKnownFolderPathPtr sGetKnownFolderPath; michael@0: }; michael@0: michael@0: #ifdef MOZ_PLACES michael@0: class AsyncFaviconDataReady MOZ_FINAL : public nsIFaviconDataCallback michael@0: { michael@0: public: michael@0: NS_DECL_ISUPPORTS michael@0: NS_DECL_NSIFAVICONDATACALLBACK michael@0: michael@0: AsyncFaviconDataReady(nsIURI *aNewURI, michael@0: nsCOMPtr &aIOThread, michael@0: const bool aURLShortcut); michael@0: nsresult OnFaviconDataNotAvailable(void); michael@0: private: michael@0: nsCOMPtr mNewURI; michael@0: nsCOMPtr mIOThread; michael@0: const bool mURLShortcut; michael@0: }; michael@0: #endif michael@0: michael@0: /** michael@0: * Asynchronously tries add the list to the build michael@0: */ michael@0: class AsyncEncodeAndWriteIcon : public nsIRunnable michael@0: { michael@0: public: michael@0: const bool mURLShortcut; michael@0: NS_DECL_THREADSAFE_ISUPPORTS michael@0: NS_DECL_NSIRUNNABLE michael@0: michael@0: // Warning: AsyncEncodeAndWriteIcon assumes ownership of the aData buffer passed in michael@0: AsyncEncodeAndWriteIcon(const nsAString &aIconPath, michael@0: uint8_t *aData, uint32_t aDataLen, uint32_t aStride, michael@0: uint32_t aWidth, uint32_t aHeight, michael@0: const bool aURLShortcut); michael@0: virtual ~AsyncEncodeAndWriteIcon(); michael@0: michael@0: private: michael@0: nsAutoString mIconPath; michael@0: nsAutoCString mMimeTypeOfInputData; michael@0: nsAutoArrayPtr mBuffer; michael@0: HMODULE sDwmDLL; michael@0: uint32_t mBufferLength; michael@0: uint32_t mStride; michael@0: uint32_t mWidth; michael@0: uint32_t mHeight; michael@0: }; michael@0: michael@0: michael@0: class AsyncDeleteIconFromDisk : public nsIRunnable michael@0: { michael@0: public: michael@0: NS_DECL_THREADSAFE_ISUPPORTS michael@0: NS_DECL_NSIRUNNABLE michael@0: michael@0: AsyncDeleteIconFromDisk(const nsAString &aIconPath); michael@0: virtual ~AsyncDeleteIconFromDisk(); michael@0: michael@0: private: michael@0: nsAutoString mIconPath; michael@0: }; michael@0: michael@0: class AsyncDeleteAllFaviconsFromDisk : public nsIRunnable michael@0: { michael@0: public: michael@0: NS_DECL_THREADSAFE_ISUPPORTS michael@0: NS_DECL_NSIRUNNABLE michael@0: michael@0: AsyncDeleteAllFaviconsFromDisk(); michael@0: virtual ~AsyncDeleteAllFaviconsFromDisk(); michael@0: }; michael@0: michael@0: class FaviconHelper michael@0: { michael@0: public: michael@0: static const char kJumpListCacheDir[]; michael@0: static const char kShortcutCacheDir[]; michael@0: static nsresult ObtainCachedIconFile(nsCOMPtr aFaviconPageURI, michael@0: nsString &aICOFilePath, michael@0: nsCOMPtr &aIOThread, michael@0: bool aURLShortcut); michael@0: michael@0: static nsresult HashURI(nsCOMPtr &aCryptoHash, michael@0: nsIURI *aUri, michael@0: nsACString& aUriHash); michael@0: michael@0: static nsresult GetOutputIconPath(nsCOMPtr aFaviconPageURI, michael@0: nsCOMPtr &aICOFile, michael@0: bool aURLShortcut); michael@0: michael@0: static nsresult michael@0: CacheIconFileFromFaviconURIAsync(nsCOMPtr aFaviconPageURI, michael@0: nsCOMPtr aICOFile, michael@0: nsCOMPtr &aIOThread, michael@0: bool aURLShortcut); michael@0: michael@0: static int32_t GetICOCacheSecondsTimeout(); michael@0: }; michael@0: michael@0: michael@0: michael@0: } // namespace widget michael@0: } // namespace mozilla michael@0: michael@0: #endif // mozilla_widget_WinUtils_h__