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 WinGesture_h__ michael@0: #define WinGesture_h__ michael@0: michael@0: /* michael@0: * nsWinGesture - Touch input handling for tablet displays. michael@0: */ michael@0: michael@0: #include "nsdefs.h" michael@0: #include michael@0: #include michael@0: #include "nsPoint.h" michael@0: #include "mozilla/EventForwards.h" michael@0: #include "mozilla/TouchEvents.h" michael@0: michael@0: // Desktop builds target apis for 502. Win8 Metro builds target 602. michael@0: #if WINVER < 0x0602 michael@0: michael@0: DECLARE_HANDLE(HGESTUREINFO); michael@0: michael@0: /* michael@0: * Gesture flags - GESTUREINFO.dwFlags michael@0: */ michael@0: #define GF_BEGIN 0x00000001 michael@0: #define GF_INERTIA 0x00000002 michael@0: #define GF_END 0x00000004 michael@0: michael@0: /* michael@0: * Gesture configuration structure michael@0: * - Used in SetGestureConfig and GetGestureConfig michael@0: * - Note that any setting not included in either GESTURECONFIG.dwWant or michael@0: * GESTURECONFIG.dwBlock will use the parent window's preferences or michael@0: * system defaults. michael@0: */ michael@0: typedef struct tagGESTURECONFIG { michael@0: DWORD dwID; // gesture ID michael@0: DWORD dwWant; // settings related to gesture ID that are to be turned on michael@0: DWORD dwBlock; // settings related to gesture ID that are to be turned off michael@0: } GESTURECONFIG, *PGESTURECONFIG; michael@0: michael@0: /* michael@0: * Gesture information structure michael@0: * - Pass the HGESTUREINFO received in the WM_GESTURE message lParam into the michael@0: * GetGestureInfo function to retrieve this information. michael@0: * - If cbExtraArgs is non-zero, pass the HGESTUREINFO received in the WM_GESTURE michael@0: * message lParam into the GetGestureExtraArgs function to retrieve extended michael@0: * argument information. michael@0: */ michael@0: typedef struct tagGESTUREINFO { michael@0: UINT cbSize; // size, in bytes, of this structure (including variable length Args field) michael@0: DWORD dwFlags; // see GF_* flags michael@0: DWORD dwID; // gesture ID, see GID_* defines michael@0: HWND hwndTarget; // handle to window targeted by this gesture michael@0: POINTS ptsLocation; // current location of this gesture michael@0: DWORD dwInstanceID; // internally used michael@0: DWORD dwSequenceID; // internally used michael@0: ULONGLONG ullArguments; // arguments for gestures whose arguments fit in 8 BYTES michael@0: UINT cbExtraArgs; // size, in bytes, of extra arguments, if any, that accompany this gesture michael@0: } GESTUREINFO, *PGESTUREINFO; michael@0: typedef GESTUREINFO const * PCGESTUREINFO; michael@0: michael@0: /* michael@0: * Gesture notification structure michael@0: * - The WM_GESTURENOTIFY message lParam contains a pointer to this structure. michael@0: * - The WM_GESTURENOTIFY message notifies a window that gesture recognition is michael@0: * in progress and a gesture will be generated if one is recognized under the michael@0: * current gesture settings. michael@0: */ michael@0: typedef struct tagGESTURENOTIFYSTRUCT { michael@0: UINT cbSize; // size, in bytes, of this structure michael@0: DWORD dwFlags; // unused michael@0: HWND hwndTarget; // handle to window targeted by the gesture michael@0: POINTS ptsLocation; // starting location michael@0: DWORD dwInstanceID; // internally used michael@0: } GESTURENOTIFYSTRUCT, *PGESTURENOTIFYSTRUCT; michael@0: michael@0: michael@0: /* michael@0: * Gesture argument helpers michael@0: * - Angle should be a double in the range of -2pi to +2pi michael@0: * - Argument should be an unsigned 16-bit value michael@0: */ michael@0: #define GID_ROTATE_ANGLE_TO_ARGUMENT(_arg_) ((USHORT)((((_arg_) + 2.0 * 3.14159265) / (4.0 * 3.14159265)) * 65535.0)) michael@0: #define GID_ROTATE_ANGLE_FROM_ARGUMENT(_arg_) ((((double)(_arg_) / 65535.0) * 4.0 * 3.14159265) - 2.0 * 3.14159265) michael@0: michael@0: /* michael@0: * Gesture configuration flags michael@0: */ michael@0: #define GC_ALLGESTURES 0x00000001 michael@0: michael@0: #define GC_ZOOM 0x00000001 michael@0: michael@0: #define GC_PAN 0x00000001 michael@0: #define GC_PAN_WITH_SINGLE_FINGER_VERTICALLY 0x00000002 michael@0: #define GC_PAN_WITH_SINGLE_FINGER_HORIZONTALLY 0x00000004 michael@0: #define GC_PAN_WITH_GUTTER 0x00000008 michael@0: #define GC_PAN_WITH_INERTIA 0x00000010 michael@0: michael@0: #define GC_ROTATE 0x00000001 michael@0: michael@0: #define GC_TWOFINGERTAP 0x00000001 michael@0: michael@0: #define GC_PRESSANDTAP 0x00000001 michael@0: michael@0: /* michael@0: * Gesture IDs michael@0: */ michael@0: #define GID_BEGIN 1 michael@0: #define GID_END 2 michael@0: #define GID_ZOOM 3 michael@0: #define GID_PAN 4 michael@0: #define GID_ROTATE 5 michael@0: #define GID_TWOFINGERTAP 6 michael@0: #define GID_PRESSANDTAP 7 michael@0: michael@0: // Maximum number of gestures that can be included michael@0: // in a single call to SetGestureConfig / GetGestureConfig michael@0: #define GESTURECONFIGMAXCOUNT 256 michael@0: michael@0: // If specified, GetGestureConfig returns consolidated configuration michael@0: // for the specified window and it's parent window chain michael@0: #define GCF_INCLUDE_ANCESTORS 0x00000001 michael@0: michael@0: // Window events we need to respond to or receive michael@0: #define WM_GESTURE 0x0119 michael@0: #define WM_GESTURENOTIFY 0x011A michael@0: michael@0: typedef struct _TOUCHINPUT { michael@0: LONG x; michael@0: LONG y; michael@0: HANDLE hSource; michael@0: DWORD dwID; michael@0: DWORD dwFlags; michael@0: DWORD dwMask; michael@0: DWORD dwTime; michael@0: ULONG_PTR dwExtraInfo; michael@0: DWORD cxContact; michael@0: DWORD cyContact; michael@0: } TOUCHINPUT, *PTOUCHINPUT; michael@0: michael@0: typedef HANDLE HTOUCHINPUT; michael@0: michael@0: #define WM_TOUCH 0x0240 michael@0: michael@0: #define TOUCHEVENTF_MOVE 0x0001 michael@0: #define TOUCHEVENTF_DOWN 0x0002 michael@0: #define TOUCHEVENTF_UP 0x0004 michael@0: #define TOUCHEVENTF_INRANGE 0x0008 michael@0: #define TOUCHEVENTF_PRIMARY 0x0010 michael@0: #define TOUCHEVENTF_NOCOALESCE 0x0020 michael@0: #define TOUCHEVENTF_PEN 0x0040 michael@0: #define TOUCHEVENTF_PALM 0x0080 michael@0: michael@0: #define TOUCHINPUTMASKF_TIMEFROMSYSTEM 0x0001 michael@0: #define TOUCHINPUTMASKF_EXTRAINFO 0x0002 michael@0: #define TOUCHINPUTMASKF_CONTACTAREA 0x0004 michael@0: michael@0: #define TOUCH_COORD_TO_PIXEL(C) (C/100) michael@0: michael@0: #define TWF_FINETOUCH 0x0001 michael@0: #define TWF_WANTPALM 0x0002 michael@0: michael@0: #endif // WINVER < 0x0602 michael@0: michael@0: // WM_TABLET_QUERYSYSTEMGESTURESTATUS return values michael@0: #define TABLET_ROTATE_GESTURE_ENABLE 0x02000000 michael@0: michael@0: class nsPointWin : public nsIntPoint michael@0: { michael@0: public: michael@0: nsPointWin& operator=(const POINTS& aPoint) { michael@0: x = aPoint.x; y = aPoint.y; michael@0: return *this; michael@0: } michael@0: nsPointWin& operator=(const POINT& aPoint) { michael@0: x = aPoint.x; y = aPoint.y; michael@0: return *this; michael@0: } michael@0: nsPointWin& operator=(int val) { michael@0: x = y = val; michael@0: return *this; michael@0: } michael@0: void ScreenToClient(HWND hWnd) { michael@0: POINT tmp; michael@0: tmp.x = x; tmp.y = y; michael@0: ::ScreenToClient(hWnd, &tmp); michael@0: *this = tmp; michael@0: } michael@0: }; michael@0: michael@0: class nsWinGesture michael@0: { michael@0: public: michael@0: nsWinGesture(); michael@0: michael@0: public: michael@0: bool SetWinGestureSupport(HWND hWnd, mozilla::WidgetGestureNotifyEvent::ePanDirection aDirection); michael@0: bool ShutdownWinGestureSupport(); michael@0: bool RegisterTouchWindow(HWND hWnd); michael@0: bool UnregisterTouchWindow(HWND hWnd); michael@0: bool GetTouchInputInfo(HTOUCHINPUT hTouchInput, uint32_t cInputs, PTOUCHINPUT pInputs); michael@0: bool CloseTouchInputHandle(HTOUCHINPUT hTouchInput); michael@0: bool IsAvailable(); michael@0: michael@0: // Simple gesture process michael@0: bool ProcessGestureMessage(HWND hWnd, WPARAM wParam, LPARAM lParam, mozilla::WidgetSimpleGestureEvent& evt); michael@0: michael@0: // Pan processing michael@0: bool IsPanEvent(LPARAM lParam); michael@0: bool ProcessPanMessage(HWND hWnd, WPARAM wParam, LPARAM lParam); michael@0: bool PanDeltaToPixelScroll(mozilla::WidgetWheelEvent& aWheelEvent); michael@0: void UpdatePanFeedbackX(HWND hWnd, int32_t scrollOverflow, bool& endFeedback); michael@0: void UpdatePanFeedbackY(HWND hWnd, int32_t scrollOverflow, bool& endFeedback); michael@0: void PanFeedbackFinalize(HWND hWnd, bool endFeedback); michael@0: michael@0: public: michael@0: // Helpers michael@0: bool GetGestureInfo(HGESTUREINFO hGestureInfo, PGESTUREINFO pGestureInfo); michael@0: bool CloseGestureInfoHandle(HGESTUREINFO hGestureInfo); michael@0: bool GetGestureExtraArgs(HGESTUREINFO hGestureInfo, UINT cbExtraArgs, PBYTE pExtraArgs); michael@0: bool SetGestureConfig(HWND hWnd, UINT cIDs, PGESTURECONFIG pGestureConfig); michael@0: bool GetGestureConfig(HWND hWnd, DWORD dwFlags, PUINT pcIDs, PGESTURECONFIG pGestureConfig); michael@0: bool BeginPanningFeedback(HWND hWnd); michael@0: bool EndPanningFeedback(HWND hWnd); michael@0: bool UpdatePanningFeedback(HWND hWnd, LONG offsetX, LONG offsetY, BOOL fInInertia); michael@0: michael@0: protected: michael@0: michael@0: private: michael@0: // Function prototypes michael@0: typedef BOOL (WINAPI * GetGestureInfoPtr)(HGESTUREINFO hGestureInfo, PGESTUREINFO pGestureInfo); michael@0: typedef BOOL (WINAPI * CloseGestureInfoHandlePtr)(HGESTUREINFO hGestureInfo); michael@0: typedef BOOL (WINAPI * GetGestureExtraArgsPtr)(HGESTUREINFO hGestureInfo, UINT cbExtraArgs, PBYTE pExtraArgs); michael@0: typedef BOOL (WINAPI * SetGestureConfigPtr)(HWND hwnd, DWORD dwReserved, UINT cIDs, PGESTURECONFIG pGestureConfig, UINT cbSize); michael@0: typedef BOOL (WINAPI * GetGestureConfigPtr)(HWND hwnd, DWORD dwReserved, DWORD dwFlags, PUINT pcIDs, PGESTURECONFIG pGestureConfig, UINT cbSize); michael@0: typedef BOOL (WINAPI * BeginPanningFeedbackPtr)(HWND hWnd); michael@0: typedef BOOL (WINAPI * EndPanningFeedbackPtr)(HWND hWnd, BOOL fAnimateBack); michael@0: typedef BOOL (WINAPI * UpdatePanningFeedbackPtr)(HWND hWnd, LONG offsetX, LONG offsetY, BOOL fInInertia); michael@0: typedef BOOL (WINAPI * RegisterTouchWindowPtr)(HWND hWnd, ULONG flags); michael@0: typedef BOOL (WINAPI * UnregisterTouchWindowPtr)(HWND hWnd); michael@0: typedef BOOL (WINAPI * GetTouchInputInfoPtr)(HTOUCHINPUT hTouchInput, uint32_t cInputs, PTOUCHINPUT pInputs, int32_t cbSize); michael@0: typedef BOOL (WINAPI * CloseTouchInputHandlePtr)(HTOUCHINPUT hTouchInput); michael@0: michael@0: // Static function pointers michael@0: static GetGestureInfoPtr getGestureInfo; michael@0: static CloseGestureInfoHandlePtr closeGestureInfoHandle; michael@0: static GetGestureExtraArgsPtr getGestureExtraArgs; michael@0: static SetGestureConfigPtr setGestureConfig; michael@0: static GetGestureConfigPtr getGestureConfig; michael@0: static BeginPanningFeedbackPtr beginPanningFeedback; michael@0: static EndPanningFeedbackPtr endPanningFeedback; michael@0: static UpdatePanningFeedbackPtr updatePanningFeedback; michael@0: static RegisterTouchWindowPtr registerTouchWindow; michael@0: static UnregisterTouchWindowPtr unregisterTouchWindow; michael@0: static GetTouchInputInfoPtr getTouchInputInfo; michael@0: static CloseTouchInputHandlePtr closeTouchInputHandle; michael@0: michael@0: // Delay load info michael@0: bool InitLibrary(); michael@0: michael@0: static HMODULE sLibraryHandle; michael@0: static const wchar_t kGestureLibraryName[]; michael@0: michael@0: // Pan and feedback state michael@0: nsPointWin mPanIntermediate; michael@0: nsPointWin mPanRefPoint; michael@0: nsPointWin mPixelScrollDelta; michael@0: bool mPanActive; michael@0: bool mFeedbackActive; michael@0: bool mXAxisFeedback; michael@0: bool mYAxisFeedback; michael@0: bool mPanInertiaActive; michael@0: nsPointWin mPixelScrollOverflow; michael@0: michael@0: // Zoom state michael@0: double mZoomIntermediate; michael@0: michael@0: // Rotate state michael@0: double mRotateIntermediate; michael@0: }; michael@0: michael@0: #endif /* WinGesture_h__ */ michael@0: michael@0: